Rails:在 rails 中使用带有 has_one 关联的 build
Posted
技术标签:
【中文标题】Rails:在 rails 中使用带有 has_one 关联的 build【英文标题】:Rails: Using build with a has_one association in rails 【发布时间】:2011-01-29 04:50:16 【问题描述】:在此示例中,我创建了一个没有 profile
的 user
,然后为该用户创建了一个 profile
。我尝试使用带有has_one
关联的构建,但结果失败了。我看到这个工作的唯一方法是使用has_many
。 user
应该最多只有一个profile
。
我一直在尝试这个。我有:
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
但是当我这样做时:
user.build_profile
我得到错误:
ActiveRecord::StatementInvalid: mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) LIMIT 1
rails 中有没有办法拥有 0 或 1 关联?
【问题讨论】:
您到底尝试了什么?能否请您发布一些代码? 【参考方案1】:build
方法签名对于 has_one
和 has_many
关联是不同的。
class User < ActiveRecord::Base
has_one :profile
has_many :messages
end
has_many
关联的构建语法:
user.messages.build
has_one
关联的构建语法:
user.build_profile # this will work
user.profile.build # this will throw error
阅读has_one
协会documentation 了解更多详情。
【讨论】:
has_one 的不同语法总是让我抓狂......该死! 有趣的是,这里评价最高和接受的答案如何回答与 OP 提出的问题不同的问题。 假设如果用户属于配置文件(意味着用户表在其表中有foreign_key profile_id),那么为用户构建配置文件也将如上所述工作,但仅用于新操作user.build_profile
用于编辑user.build_profile if user.profile.nil?
如果您想在创建用户时构建配置文件,请在用户模型中写入accepts_nested_attributes_for :profile
this。并在创建用户的表单中写下<%= f.simple_fields_for :profile do |p| %>
this 并继续。
但是为什么 has_one 或 has_many 会保留这种不同的行为呢?我认为并期望在设计时会有一些原因。
@Ajedi32 答案与问题的标题匹配,但与正文不匹配。鉴于此 (build_<association>
) 在 Rails 中是一种非常奇怪且出乎意料的行为,如果您明白我的意思,那么寻找此答案的人比实际问题的答案要多得多。【参考方案2】:
仔细查看错误消息。它告诉您 个人资料表 中没有必填列 user_id
。
在模型中设置关系只是答案的一部分。
您还需要创建一个迁移,将user_id
列添加到配置文件表中。
Rails 期望它存在,如果不是,您将无法访问配置文件。
欲了解更多信息,请查看此链接:
Association Basics
【讨论】:
我刚刚发现了我的问题。我正在学习的那本书没有很好地解释外键的创建。我创建了一个新的迁移,它为我的模型添加了一个外键。谢谢。 每次都需要自己创建栏目吗?我有这样的想法,它是自动发生的。我不知道我从哪里得到这个想法。 您可以在使用命令行生成模型时添加列,例如rails g model profile user:references:index address:string bio:text
。【参考方案3】:
应该是has_one
。如果build
不起作用,您可以使用new
:
ModelName.new( :owner => @owner )
与
相同@owner.model_names.build
【讨论】:
这不一样:如果你用 build 创建一个新的 model_name,当 @owner 被保存时,新的 model_name 也会被保存。因此,您可以使用 build 来创建将一起保存的父母和孩子。如果您使用 .new 制作模型名称,则情况并非如此以上是关于Rails:在 rails 中使用带有 has_one 关联的 build的主要内容,如果未能解决你的问题,请参考以下文章
Rails 5,带有 Select2-rails 的简单表单
如何在带有 Rails 4.2 的专用调试端口上使用工头启动 Rails?
使用 mongoid 在 rails 中保存带有嵌入对象/文档的对象