Rails:拥有并且属于许多(HABTM) – 创建关联而不创建其他记录
在Google上花了一整天,但找不到答案。 :\
我在用户和Core_Values之间有HABTM关系。
class CoreValue < ActiveRecord::Base has_and_belongs_to_many :users class User < ActiveRecord::Base has_and_belongs_to_many :core_values
在我的控制器中,我需要做两件事:
- 如果CoreValue不存在,请创建一个新的并将其与给定的用户ID相关联,并且
- 假设我知道特定的CoreValue确实存在,则创建关联而不创建任何新的CoreValues或Users
对于#1,我有这个工作:
User.find(current_user.id).core_values.create({:value => v, :created_by => current_user.id})
这将创建一个新的CoreValue:value和:created_by并创建关联。
对于#2,我尝试了一些东西,但似乎不太可能只创建关联。
谢谢你的帮助!
您可以使用非常有用的find_or_create
方法find_or_create
执行此操作。 find_or_create
将首先尝试查找记录,如果它不存在,则创建它。 像这样的东西应该做的伎俩:
core_value = CoreValue.find_or_create_by_value(v, :created_by => current_user.id) current_user.core_values << core_value
一些说明:
- 第一行将找到或创建值
v
。 如果它不存在并且已创建,则会将created_by
设置为current_user.id
。 - 不需要执行
User.find(current_user.id)
,因为它将返回与current_user
相同的对象。 -
current_user.core_values
是一个数组,您可以使用<<
轻松地为其添加另一个值。
为简洁起见,以下内容与上面的代码示例相同:
current_user.core_values << CoreValue.find_or_create_by_value(v, :created_by => current_user.id)
在您的用户模型中添加方法:
class User < ActiveRecord::Base def assign_core_value(v) core_values.find_by_name(v) || ( self.core_values << CoreValue.find_or_create_by_name(:name => v, :created_by => self)).last end end
assign_core_value
方法满足要求1,2并返回分配给用户的核心值(具有给定名称)。
现在您可以执行以下操作:
current_user.assign_core_value(v)
注1
方法逻辑如下:
1)检查CoreValue是否已与用户关联。 如果是这样,则不执行任何操作,则返回核心值。
2)检查具有给定名称的CoreValue是否存在。 如果没有创建CoreValue。 将核心值(创建/找到)与用户相关联。
Active Record已经为您提供了一种方法。 在你的情况下,
val = CoreValue.find_by_value(v) current_user.core_values << val
您也可以通过这种方式传递大量对象。 将创建所有关联
请查看此以获取更多信息
- Rails accepted_nested_attributes_for始终创建嵌套模型,但不更新它们
- 订购ActiveRecord关系对象
- rails中的交叉唯一性模型validation
- 从范围记录计算总数百分比并显示虚拟属性(Rails / Active Record)
- Rails:包含多态关联
- ActiveRecord … activerecord-mysql-adapter
- Rails ActiveRecord:是否可以组合:include和:conditions查询?
- ROR中3路habtm的自定义数据库条目
- counter_cache has_many_through sql optimization,减少sql查询次数