开发者

What's the actual class of a has_many relation?

开发者 https://www.devze.com 2023-02-11 05:04 出处:网络
Basic primer: class User has_man开发者_如何学编程y :programs, :through => :memberships has_many :memberships

Basic primer:

class User 
  has_man开发者_如何学编程y :programs, :through => :memberships
  has_many :memberships
end

class Program
end

class Membership
  belongs_to :user
  belongs_to :program
end

Console:

User.new.save
Program.new.save
User.programs << Program.first

User.first.programs.class
# => Array
User.first.programs.methods.grep /where/
# => []
User.first.programs.where :id => 1
# => [#<Program id: 1>]
User.first.programs.where(:id => 1).class
# => ActiveRecord::Relation

So the question is that User.first.programs, the has_many method, seems to return a result that barks like an ActiveRecord::Relation and accepts methods like a Relation, but self-identifies as an Array and shares its methods with an instance of class Array.

So what gives?


It's indeed surprising and don't know if it was the best solution, but at least it's documented (in the AssociationProxy class):

the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.

This class has most of the basic instance methods removed, and delegates unknown methods to @target via method_missing. As a corner case, it even removes the class method and that’s why you get

blog.posts.class # => Array though the object behind blog.posts is not an Array, but an ActiveRecord::Associations::HasManyAssociation.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号