是否可以在表上包含以下两列,并使用active_record保存它们:
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 %>
强大的参数:
def blog_params
params.require(:blog).permit(:user_name, :user_name_id)
end
当我提交表单以创建新的blog
时,它会出错。 params hash看起来不错:
“blog”=>{“user_name_id"=>"1", “user_name"=>”foo”}
但是我收到以下错误:
的ActiveRecord :: AssociationTypeMismatch 用户名(#70119900697480)预期,得到字符串(#70119800086640)
更新:我理解这一点,理想情况是:其中一个属性的列名应该更改。尽管如此:是否可能使用rails执行此操作?需要什么?
答案 0 :(得分:2)
从上面的答案中可以明显看出这个问题 - 将user_name
属性更改为其他内容。
作为最后的手段,这可能是一个糟糕的建议,但您甚至可以尝试声明您正在使用的属性:
class Blog < ApplicationRecord
belongs_to :user_name, through: :user_name_id
end
但同样,您关联记录的原因是,您可以通过关联随时调用user_name,并获取存储在那里的所有信息。这意味着,您不需要将user_name与blog一起存储...因为您已经通过了user_name关联。
答案 1 :(得分:1)
作者更新的更新:
belongs_to :your_new_belons_to_name, class_name: 'NameUser', foreign_key: 'name_user_id'
答案 2 :(得分:0)
当你这样做时:
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
。这正是错误告诉你的。
另外,我同意Alexey。我不知道为什么你会在user_name
上坚持Blog
(作为一个字符串)。如果班级UserName
具有name
属性,那么您可以随时执行以下操作:
blog.user_name.name
我也同意Alexey的观点,UserName
是一个奇怪的类名。 Alexey关于命名的建议很好,所以请考虑一下。