- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
让我们使用这些类:
class User < ActiveRecord::Base
has_many :project_participations
has_many :projects, through: :project_participations, inverse_of: :users
end
class ProjectParticipation < ActiveRecord::Base
belongs_to :user
belongs_to :project
enum role: { member: 0, manager: 1 }
end
class Project < ActiveRecord::Base
has_many :project_participations
has_many :users, through: :project_participations, inverse_of: :projects
end
user
可以参加很多
projects
角色为
member
或
manager
.连接模型称为
ProjectParticipation
.
# first example
u = User.new
p = Project.new
u.projects << p
u.projects
=> #<ActiveRecord::Associations::CollectionProxy [#<Project id: nil>]>
u.project_participations
=> #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil>]>
ProjectParticipation
我自己可以访问
projects
的
user
与
u.projects
.
ProjectParticipation
则不起作用我自己:
# second example
u = User.new
pp = ProjectParticipation.new
p = Project.new
pp.project = p # assign project to project_participation
u.project_participations << pp # assign project_participation to user
u.project_participations
=> #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil>]>
u.projects
=> #<ActiveRecord::Associations::CollectionProxy []>
u.projects
访问项目就像之前一样。
u.project_participations.map(&:project)
=> [#<Project id: nil>]
u.projects
将所有项目返回给我,不取决于我是否自己创建连接对象?或者我怎样才能让 AR 意识到这一点?
最佳答案
简答 : 不,第二个例子不会像第一个例子那样工作。您必须使用第一个示例的方式直接与用户和项目对象创建中间关联。
长答案 :
在开始之前,我们应该知道has_many :through
正在处理 ActiveRecord::Base
.所以,让我们从 has_many(name, scope = nil, options = {}, &extension)
开始吧。调用其关联的方法builder here , 在方法结束时返回 reflection然后将反射添加到 hash作为缓存 with key-value pair here .
现在的问题是,这些关联是如何被激活的?!?!
这是因为 association(name)
方法。调用 association_class
方法,它实际调用并返回这个常量: Associations::HasManyThroughAssociation
, 这使得 this line自动加载 active_record/associations/has_many_through_association.rb 和 instantiate its instance here .这是owner and reflection在创建关联和调用下一个重置方法时保存,该方法在子类 ActiveRecord::Associations::CollectionAssociation
中调用here .
为什么这个重置电话很重要?因为,它设置了 @target
作为一个数组。这个@target
是在您进行查询时存储所有关联对象的数组,然后在您在代码中重用它而不是进行新查询时用作缓存。这就是为什么调用 user.projects
(其中用户和项目在数据库中持续存在,即调用: user = User.find(1)
然后 user.projects
)将进行数据库查询并且再次调用它不会。
因此,当您制作 reader调用关联,例如:user.projects
, 它invokes the collectionProxy , 在填充 @target
之前来自 load_target
.
这只是触及表面而已。但是,您会了解如何使用构建器(根据条件创建 different reflection)构建关联并创建代理以读取目标变量中的数据。
tl;博士
您的第一个和第二个示例之间的区别在于它们的关联构建器被调用以创建关联的反射 (based on macro) ,代理和目标实例变量。
第一个例子:
u = User.new
p = Project.new
u.projects << p
u.association(:projects)
#=> ActiveRecord::Associations::HasManyThroughAssociation object
#=> @proxy = #<ActiveRecord::Associations::CollectionProxy [#<Project id: nil, name: nil, created_at: nil, updated_at: nil>]>
#=> @target = [#<Project id: nil, name: nil, created_at: nil, updated_at: nil>]
u.association(:project_participations)
#=> ActiveRecord::Associations::HasManyAssociation object
#=> @proxy = #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil, created_at: nil, updated_at: nil>]>
#=> @target = [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil, created_at: nil, updated_at: nil>]
u.project_participations.first.association(:project)
#=> ActiveRecord::Associations::BelongsToAssociation object
#=> @target = #<Project id: nil, name: nil, created_at: nil, updated_at: nil>
第二个例子:
u = User.new
pp = ProjectParticipation.new
p = Project.new
pp.project = p # assign project to project_participation
u.project_participations << pp # assign project_participation to user
u.association(:projects)
#=> ActiveRecord::Associations::HasManyThroughAssociation object
#=> @proxy = nil
#=> @target = []
u.association(:project_participations)
#=> ActiveRecord::Associations::HasManyAssociation object
#=> @proxy = #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil, created_at: nil, updated_at: nil>
#=> @target = [#<ProjectParticipation id: nil, user_id: nil, project_id: nil, role: nil, created_at: nil, updated_at: nil>]
u.project_participations.first.association(:project)
#=> ActiveRecord::Associations::BelongsToAssociation object
#=> @target = #<Project id: nil, name: nil, created_at: nil, updated_at: nil>
BelongsToAssociation
没有代理, 它只有
target and owner .
u.association(:projects).instance_variable_set('@target', [p])
现在:
u.projects
#=> #<ActiveRecord::Associations::CollectionProxy [#<Project id: nil, name: nil, created_at: nil, updated_at: nil>]>
在我看来,这是一种非常糟糕的创建/保存关联的方式。所以,坚持第一个例子本身。
关于ruby-on-rails - Rails/ActiveRecord has_many 到 : association on unsaved objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26651811/
我有一个具有以下模型的应用程序:- 类别- 子类别- 产品- 产品子类别 我的关系如下: Category has_many :subcategories Subcategory belongs_to
看来 rails 仍然不支持这种类型的关系并抛出 ActiveRecord::HasManyThroughAssociationPolymorphicThroughError 错误。 我该怎么做才能实
我想知道我可以在多大程度上使用 Rails 中的关联。考虑以下因素: class User :provider end class Provider :businesses belongs
我是 Rails 的新手。我想知道我是否需要将 add_index 添加到两个迁移? 我正在尝试定义用户和事件。每个用户可以有多个事件,每个事件可以有多个用户。所以我会做这样的事情: class Us
我有这个: class User :series end class Serial :serials end class Episode < ActiveRecord::Base belong
我一直致力于一个大量使用模型关联的项目,似乎我发现了 has_many 或 has_one through 功能与 :conditions 功能冲突的情况。简而言之,问题是 through 关联为 h
模拟以下情况的最佳方法是什么: Word belongs_to :wordable, :polymorphic => true Phrase has_many :words, :as => :
这似乎是一个典型的问题,但很难搜索。 我想选择用户通过 has_many 拥有的项目和用户通过 has_many through 关联的项目。 考虑以下模型: class User < ActiveR
首先对英语感到抱歉 所以我已经有了“用户 - 帖子”一对多关联,这意味着每个帖子只能有一个作者,现在我想在用户个人资料中添加“最喜欢的帖子”按钮,以及“添加到收藏夹”按钮每个帖子,所以问题是如何实现这
我有一个用户模型,允许用户关注其他用户。每个用户也有很多东西: class User has_many :following, :class_name => 'Followings', :fore
我正在使用 Rails 4.1 和 Ruby 2.1。 一个用户 has_many 辆车,和一辆车 has_many 约会。获取所有用户约会的最简单方法是什么? 理想情况下,我想做这样的事情:user
我想为 has_many/has_many 关系定义一个工厂(我想我做对了)但是我不知道如何为这些创建的工厂的每个对象定义属性。 这是主页,这是交易卡片的列表 我们假设下面的主页 View 是针对登录
我正在努力弄清楚如何实现这个计数。模型是用户、测试、等级 用户 has_many 测试,测试 has_many 成绩。 每个等级都有一个计算分数(strong_pass、pass、fail、stron
我有一个 has many through 关系来定义用户已回答的问题。 如何为用户创建的问题建立关系? 通常你会在用户和问题之间创建一个 has_many 和 belongs_to 关系,但是因为我
例如,在 class Student < ActiveRecord::Base has_many :awards end class Awards < ActiveRecord::Base b
我仍然在尝试如何处理在Ecto中创建/更新has_many, through:关联。我已经重新阅读了José's关于关联以及the docs的帖子,但我仍在努力。 我所拥有的是: 网站/模型/dish
# == Schema Information # # Table name: orders # # id :integer not null, pri
我正在尝试从 EventView.promoter_id = User.id 的用户获取事件,但它无法正常工作。这是我的设置(目前不正确): User has_many :events has_man
我有三门课 TeamMember , Service和ServiceTeamMember 我有 class Service has_many :service_team_members has
我需要列出所有用户及其销售的产品总量及其电子邮件和产品总量, class User :user).group('users.email').sum(:quantity) 关于mysql - 事件记录
我是一名优秀的程序员,十分优秀!