Ruby-on-rails 在 rails 中使用带有 has_one 关联的构建

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2472982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:25:29  来源:igfitidea点击:

Using build with a has_one association in rails

ruby-on-railsassociationshas-onedatabase-relations

提问by espinet

In this example, I create a userwith no profile, then later on create a profilefor that user. I tried using build with a has_oneassociation but that blew up. The only way I see this working is using has_many. The useris supposed to only have at most one profile.

在这个例子中,我创建了一个userno profile,然后profile为该用户创建了一个。我尝试使用带有has_one关联的构建,但失败了。我看到这个工作的唯一方法是使用has_many. 本user应该只有最多只能有一个profile

I have been trying this. I have:

我一直在尝试这个。我有:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

But when I do:

但是当我这样做时:

user.build_profile 

I get the error:

我收到错误:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4)  LIMIT 1

Is there a way in rails to have 0 or 1 association?

rails 有没有办法让 0 或 1 关联?

回答by Harish Shetty

The buildmethod signature is different for has_oneand has_manyassociations.

和关联的build方法签名不同 。has_onehas_many

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

The build syntax for has_manyassociation:

has_many关联的构建语法:

user.messages.build

The build syntax for has_oneassociation:

has_one关联的构建语法:

user.build_profile  # this will work

user.profile.build  # this will throw error

Read the has_oneassociation documentationfor more details.

阅读has_one关联文档以获取更多详细信息。

回答by sosborn

Take a good look at the error message. It is telling you that you do not have required column user_idin the profile table. Setting the relationships in the model is only part of the answer.

仔细看看错误信息。它告诉您user_id配置文件表中没有 required 列。在模型中设置关系只是答案的一部分。

You also need to create a migration that adds the user_idcolumn to the profile table. Rails expects this to be there and if it is not you cannot access the profile.

您还需要创建一个将user_id列添加到配置文件表的迁移。Rails 希望它在那里,如果没有,您将无法访问该配置文件。

For more information please take a look at this link:

有关更多信息,请查看此链接:

Association Basics

协会基础

回答by Shiyason

Depending on the use case, it can be convenient to wrap the method and automatically build the association when not found.

根据用例,可以方便地包装方法并在未找到时自动构建关联。

old_profile = instance_method(:profile)
define_method(:profile) do
  old_profile.bind(self).call || build_profile
end

now calling the #profilemethod will either return the associated profile or build a new instance.

现在调用该#profile方法将返回关联的配置文件或构建一个新实例。

source: When monkey patching a method, can you call the overridden method from the new implementation?

来源: 当猴子修补一个方法时,你能从新的实现中调用被覆盖的方法吗?

回答by Karl

It should be a has_one. If buildisn't working, you can just use new:

它应该是一个has_one. 如果build不起作用,您可以使用new

ModelName.new( :owner => @owner )

is the same as

是相同的

@owner.model_names.build