Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many-To-Many Relationship #120

Open
gioch opened this issue Apr 12, 2016 · 7 comments
Open

Many-To-Many Relationship #120

gioch opened this issue Apr 12, 2016 · 7 comments

Comments

@gioch
Copy link

gioch commented Apr 12, 2016

How can i define many to many relationship?
When i set has_many through relationship, console says this:
NoMethodError: undefined method relation_delegate_class for Permission:Class from lib/ruby/gems/2.3.0/gems/active_hash-1.4.0/lib/active_hash/base.rb:239:in method_missing

@al2o3cr
Copy link
Collaborator

al2o3cr commented Aug 11, 2017

FWIW, ust encountered this in a Rails 5.1 app. Adding the right module from ActiveRecord made it go away:

class ActiveHash::Base
  extend ::ActiveRecord::Delegation::DelegateCache
end

Hit some other missing pieces, tho (arel_table not defined). Will investigate further, I'm assuming this means ActiveHash isn't quacking to all the right things anymore.

@kbrock
Copy link
Collaborator

kbrock commented Aug 11, 2017

@al2o3cr nice.

Is the thought to conditionally add this to ActiveHash::Base based upon active record version?

@coreyward
Copy link

@al2o3cr Did you get any further with the arel_table issue? Running into the same thing here after I (separately) did the same thing you did w/ DelegateCache.

@coreyward
Copy link

coreyward commented Aug 12, 2017

I went ahead and built a new Arel::Table instance to see what broke next. Looks like I need to construct a PredicateBuilder instance, and documentation there is scarce.

class ActiveHash::Base
  extend ActiveRecord::Delegation::DelegateCache

  def self.arel_table
    Arel::Table.new(name.tableize)
  end
end

Raises undefined method 'predicate_builder' from this call.

Update

Not sure how robust this is, but it's getting a basic test green for me until I do something that requires a join.

class ActiveHash::Base
  extend ActiveRecord::Delegation::DelegateCache
  include ActiveRecord::Attributes

  class << self
    def table_name
      name.tableize
    end

    def arel_table
      Arel::Table.new(table_name)
    end

    def predicate_builder
      ActiveRecord::PredicateBuilder.new(arel_table)
    end

    def reload_schema_from_cache; end

    def type_for_attribute(attr_name)
      attributes_to_define_after_schema_loads.fetch(attr_name.to_s).first
    end

    def type_caster
      self
    end

    def connection
      self
    end

    def unscoped
      self
    end

    def extending!(*args)
      self
    end
  end
end

I should note this requires using the Attributes API on the models as well. This could be coalesced with the ActiveHash typing, but I didn't bother:

class Foo < ActiveHash::Base
  attribute :id, ActiveModel::Type::Integer.new
  attribute :name, ActiveModel::Type::String.new
end

@al2o3cr
Copy link
Collaborator

al2o3cr commented Aug 16, 2017

@coreyward I glued together a handful more methods (like you've shown) and then realized I'd need to make the join machinery work with ActiveHash to get this working. 😱

Currently trying out using a Postgres array column (foo_ids) that loads ActiveHash objects when you call foos.

@coreyward
Copy link

@al2o3cr I wound up aborting after re-discovering that @zilkey has stated previously a lack of desire to allow an ActiveRecord object to belongs_to ActiveHash objects (something, something, persistence of static object to datastore, something, something).

I like the notion of using a Postgres array column, but I think it still needs to quack like an AR join to allow for the relationships to work. We really need some brave and patient soul to document the current ActiveRecord associations code more extensively.

@al2o3cr
Copy link
Collaborator

al2o3cr commented Aug 17, 2017

@coreyward The models in the app I'm working on are pretty simple, so we've avoided the join stuff for now. Here's a sample:

class Student < ApplicationRecord
  # column: skill_ids
  def skills
    @_skills ||= Skill.find(skill_ids)
  end

  def skill_ids=(ids)
    super
    @_skills = nil # flush our cache
  end
end

We search these models with Ransack and it seems to be working well. There's not been a call for the relationship connecting a single Skill to many Student records.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants