[英]Rails: ActiveRecord::AssociationTypeMismatch error
Is it possible to have the following two columns on an table and save them with active_record: 是否可以在表上包含以下两列并使用active_record保存它们:
user_name_id
(which is an association) user_name_id
(这是一个关联) user_name
(just text) user_name
(只是文本) To demonstrate an attempt to save the association field user_name_id
and the text field user_name
演示尝试保存关联字段user_name_id
和文本字段user_name
Here are the models: 以下是模型:
#app/models/blog.rb
class Blog < ApplicationRecord
belongs_to :user_name
end
#app/models/user_name.rb
class UserName < ApplicationRecord
has_many :blogs
end
The form: 表格:
<%= form_for(blog) do |f| %>
<% if blog.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(blog.errors.count, "error") %> prohibited this blog from being saved:</h2>
<ul>
<% blog.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div class="field">
<%= f.label :user_name_id %>
<%= f.collection_select :user_name_id, UserName.all, :id, :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The strong params: 强大的参数:
def blog_params
params.require(:blog).permit(:user_name, :user_name_id)
end
When I submit the form in order to create a new blog
, it errors out. 当我提交表单以创建新blog
,它会出错。 The params hash looks ok: params hash看起来不错:
“blog”=>{“user_name_id"=>"1", “user_name"=>”foo”}
However I am getting the following error: 但是我收到以下错误:
ActiveRecord::AssociationTypeMismatch UserName(#70119900697480) expected, got String(#70119800086640) ActiveRecord :: AssociationTypeMismatch用户名(#70119900697480)预期,得到字符串(#70119800086640)
Update : I understand that, ideally: the column name of one of these attributes should change. 更新 :我理解,理想情况下:其中一个属性的列名应该更改。 Nonetheless: is it possible to do this with rails? 尽管如此: 是否可以使用rails进行此操作? What would it take? 需要什么?
The issue is obvious from the answers above - change user_name
attribute to be called something else. 从上面的答案中可以明显看出这个问题 - 将user_name
属性更改为其他名称。
As a very last resort, this might be a bad suggestion, but you could even try to declare which attribute you're using like: 作为最后的手段,这可能是一个糟糕的建议,但您甚至可以尝试声明您正在使用的属性:
class Blog < ApplicationRecord
belongs_to :user_name, through: :user_name_id
end
But again, the reason you're associating the records, is so that you can call user_name at any point, through the association, and get all the information stored there. 但同样,您关联记录的原因是,您可以通过关联随时调用user_name,并获取存储在那里的所有信息。 Meaning, you don't need to store the user_name with the blog... because you already are through the user_name association. 这意味着,您不需要将user_name与博客存储...因为您已经通过了user_name关联。
UPDATE for authors' update: 作者更新的更新:
belongs_to :your_new_belons_to_name, class_name: 'NameUser', foreign_key: 'name_user_id'
When you do: 当你这样做时:
belongs_to :user_name
ActiveRecord assumes that Blog
has an attribute user_name_id
(which it looks like you have - so far, so good). ActiveRecord假设Blog
有一个属性user_name_id
(它看起来像你一样 - 到目前为止,非常好)。 As stated in the Guide , you also get a setter method, user_name=
which expects that you're going to pass it a UserName
instance. 如指南中所述,您还会获得一个setter方法user_name=
,它希望您将其传递给UserName
实例。
When you do something like: 当你做类似的事情时:
Blog.new(“user_name_id"=>"1", “user_name"=>”foo”)
ActiveRecord is expecting user_name
to be an instance of class UserName
. ActiveRecord期望user_name
是UserName
类的实例。 But you just passed it a String
. 但你只是传递了一个String
。 Which is exactly what the error is telling you. 这正是错误告诉你的。
Also, I agree with Alexey. 此外,我同意阿列克谢。 I don't know why you would persist user_name
(as a string) on Blog
. 我不知道为什么你会在Blog
上持久化user_name
(作为字符串)。 If the class UserName
has a name
attribute, then you can always just do something like: 如果UserName
类具有name
属性,那么您可以始终执行以下操作:
blog.user_name.name
I also agree with Alexey that UserName
is a weird class name. 我也同意Alexey, UserName
是一个奇怪的类名。 Alexey's recommendations on naming are good ones, so please consider them. Alexey关于命名的建议很好,所以请考虑一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.