简体   繁体   English

Rails:ActiveRecord :: AssociationTypeMismatch错误

[英]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关联。

  1. You should not use 'user_name' field at all if you already use belongs_to 'user_name'. 如果您已经使用belongs_to'user_name',则根本不应使用'user_name'字段。
  2. Please do not call Model 'UserName' this is not good, maybe this is UserProfile or just User? 请不要调用Model'UserName'这不好,也许这是UserProfile或只是用户?
  3. Are you sure you want to cache user_name for your blog? 您确定要为您的博客缓存user_name吗? If user will change his name it will makes many problems. 如果用户将更改他的名字,将会产生许多问题。 If you want to cache user_name for blog anyway you can rename column on 'user_name_cached' and updates it on 'UserName' will updates on before_save callback. 如果你想为blog更新user_name,你可以重命名'user_name_cached'上的列并在'UserName'上更新它将在before_save回调上更新。

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_nameUserName类的实例。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM