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)

更新:我的理解是,最好是:这些属性之一的列名应该改变。尽管如此:是否有可能与轨道做到这一点?需要什么?

+0

显示博客的两个模型和控制器 – gates

+0

博客是否属于名为user_name或user的表? – gwalshington

+0

属于一个名为user_names的实际表格 – Neil

的问题是,从上面的答案显而易见 - 改变user_name属性被称为别的东西。

作为最后的手段,这可能是一个坏的建议,但你甚至可以尝试申报哪个属性您要使用如:

class Blog < ApplicationRecord 
    belongs_to :user_name, through: :user_name_id 
end 

但同样,原因你关联的记录,这样你就可以在任何时候通过关联调用user_name,并获得存储在那里的所有信息。这意味着,您不需要将user_name与博客一起存储......因为您已经通过了user_name关联。

+0

没有必要通过;) – gates

+0

如果你保留了这两个属性,通过声明你正在关联的属性来分开它们。这就是为什么他首先解决了这个问题。 – gwalshington

+0

不幸的是,在应用程序中,无法更改两个表列名称。带'_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_nameUserName类的一个实例。但你只是通过了String。这正是错误告诉你的。

另外,我同意阿列克谢。我不知道为什么你会坚持user_name(作为字符串)在Blog。如果该类UserNamename属性,那么你永远可以这样做:

blog.user_name.name 

我也同意这阿列克谢是UserName一个奇怪的类名。阿列克谢关于命名的建议是很好的,所以请考虑他们。

+0

请参阅最新的问题。这只是一个快速演示代码来演示这个问题。 – Neil

  1. 如果您已经使用belongs_to'user_name',则根本不应该使用'user_name'字段。
  2. 请不要调用Model'UserName'这不好,也许这是UserProfile或只是用户?
  3. 您确定要为您的博客缓存user_name吗?如果用户改变他的名字,将会产生很多问题。如果您想缓存user_name for blog,您可以重命名'user_name_cached'列,并在'UserName'上更新它将更新before_save回调。
  4. 对作者的更新

UPDATE:

belongs_to :your_new_belons_to_name, class_name: 'NameUser', foreign_key: 'name_user_id'

+0

请查看最新的问题。这只是一个快速演示代码来演示这个问题。 – Neil

+0

好吧请看我的更新 – AlexeyKuznetsov

+0

如果你想安全原始的'user_name'方法名我认为你必须编写你自己的getter/setter方法 'def user name; UserName.where(id:self.user_name_id).first || self.user_name; end ' – AlexeyKuznetsov