Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Add has_and_belongs_to_many via has_many :through #48

@sfcgeorge

Description

@sfcgeorge

This code implements has_and_belongs_to_many in Hyperloop by using the existing has_many :through functionality and dynamically generating the join table.

if RUBY_ENGINE == "opal"
  module ActiveRecord
    module ClassMethods
     def has_and_belongs_to_many(assoc, scope=nil, **options)
        other = assoc.singularize
        name = self.name.downcase
        rassoc = name.pluralize
        habtm_name = [assoc, rassoc].sort.join("_") # alphabetical order
        habtm_class = habtm_name.singularize.camelize

        has_many habtm_name # regular has_many makes the through work
        has_many assoc, **options.merge(through: habtm_name)

        return if ::Object.const_defined?(habtm_class) # prevent duplication

        # double colon before Object and Class are needed - Opal bug?
        ::Object.const_set(
          habtm_class, ::Class.new(::ActiveRecord::Base) do
            belongs_to other, foreign_key: "#{other}_id", inverse_of: assoc
            belongs_to name, foreign_key: "#{name}_id", inverse_of: rassoc
          end
        )
      end
    end
  end
end

Note that this patch alone only enables read only access. This is because Hyperloop doesn't support writing to has_many :through e.g. with the << method (but Rails does). You can't work around it by trying to create the join table directly because it doesn't exist on the server side so execute_remote fails.

The inverse_of isn't necessary but can't hurt I think. I hoped it would make the association writeable but it doesn't.

Needs tests adding to test_app.

Tested in lap17 and Opal 0.10

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions