Rails的:ActiveRecord的:: AssociationTypeMismatch错误
是否有可能有上表中的以下两列,并将它们保存与active_record:Rails的:ActiveRecord的:: AssociationTypeMismatch错误
-
user_name_id
(这是一个协会) -
user_name
(只是文本)
为了证明试图挽救联想场user_name_id
和文本字段user_name
下面是型号:
#app/models/blog.rb
class Blog < ApplicationRecord
belongs_to :user_name
end
#app/models/user_name.rb
class UserName < ApplicationRecord
has_many :blogs
end
形式:
<%= 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 %>
强PARAMS:
def blog_params
params.require(:blog).permit(:user_name, :user_name_id)
end
当我为了创建一个新的blog
提交表单,它出错了。 params哈希表看起来不错:
“blog”=>{“user_name_id"=>"1", “user_name"=>”foo”}
但是我收到以下错误:
ActiveRecord::AssociationTypeMismatch UserName(#70119900697480) expected, got String(#70119800086640)
更新:我的理解是,最好是:这些属性之一的列名应该改变。尽管如此:是否有可能与轨道做到这一点?需要什么?
的问题是,从上面的答案显而易见 - 改变user_name
属性被称为别的东西。
作为最后的手段,这可能是一个坏的建议,但你甚至可以尝试申报哪个属性您要使用如:
class Blog < ApplicationRecord
belongs_to :user_name, through: :user_name_id
end
但同样,原因你关联的记录,这样你就可以在任何时候通过关联调用user_name,并获得存储在那里的所有信息。这意味着,您不需要将user_name与博客一起存储......因为您已经通过了user_name关联。
没有必要通过;) – gates
如果你保留了这两个属性,通过声明你正在关联的属性来分开它们。这就是为什么他首先解决了这个问题。 – gwalshington
不幸的是,在应用程序中,无法更改两个表列名称。带'_id'的列表示关联(如果存在),没有'_id'的列表示集合中未列出的名称。 – Neil
当你这样做:
belongs_to :user_name
ActiveRecord的假设Blog
有一个属性user_name_id
(它看起来你有 - 到目前为止,那么好)。如Guide中所述,您还会收到一个setter方法,user_name=
,期望您将其传递给UserName
实例。
当你做这样的事情:
Blog.new(“user_name_id"=>"1", “user_name"=>”foo”)
ActiveRecord的期待user_name
是UserName
类的一个实例。但你只是通过了String
。这正是错误告诉你的。
另外,我同意阿列克谢。我不知道为什么你会坚持user_name
(作为字符串)在Blog
。如果该类UserName
有name
属性,那么你永远可以这样做:
blog.user_name.name
我也同意这阿列克谢是UserName
一个奇怪的类名。阿列克谢关于命名的建议是很好的,所以请考虑他们。
请参阅最新的问题。这只是一个快速演示代码来演示这个问题。 – Neil
- 如果您已经使用belongs_to'user_name',则根本不应该使用'user_name'字段。
- 请不要调用Model'UserName'这不好,也许这是UserProfile或只是用户?
- 您确定要为您的博客缓存user_name吗?如果用户改变他的名字,将会产生很多问题。如果您想缓存user_name for blog,您可以重命名'user_name_cached'列,并在'UserName'上更新它将更新before_save回调。 对作者的更新
UPDATE:
belongs_to :your_new_belons_to_name, class_name: 'NameUser', foreign_key: 'name_user_id'
请查看最新的问题。这只是一个快速演示代码来演示这个问题。 – Neil
好吧请看我的更新 – AlexeyKuznetsov
如果你想安全原始的'user_name'方法名我认为你必须编写你自己的getter/setter方法 'def user name; UserName.where(id:self.user_name_id).first || self.user_name; end ' – AlexeyKuznetsov
显示博客的两个模型和控制器 – gates
博客是否属于名为user_name或user的表? – gwalshington
属于一个名为user_names的实际表格 – Neil