我正在尝试使用collection_select(使用bootstrap_form_for)来保存相关记录。使用Rails控制台保存效果很好,所以我假设模型定义很好(控制器代码也是如此)。
型号: 用户-
class User < ApplicationRecord
validates :name, presence: true, length: {maximum: 50}
validates :email, presence: true, length: {maximum: 250}, uniqueness: true
has_secure_password
validates :password, length: {minimum: 6}
belongs_to :role
has_many :issues_owned, :class_name => 'Issue', :foreign_key => 'owner'
has_many :issues_assigned, :class_name => 'Issue', :foreign_key => 'assigned_to'
end
模型问题-
class Issue < ApplicationRecord
belongs_to :assigned_to, :class_name => 'User'
belongs_to :owner, :class_name => 'User'
validates :summary, presence: true, length: {maximum: 100}
validates :description, presence: true, length: {maximum: 250}
validates :severity, presence: true, length: {maximum: 10}
validates :priority, presence: true, length: {maximum: 10}
end
添加问题的表单代码-
<%= bootstrap_form_for(@issue, layout: :horizontal, label_col: "col-sm-2") do |form| %>
<%= form.text_field :summary, control_col: 'col-md-4',class: 'input-sm' %>
<%= form.text_area :description, control_col: 'col-md-8', class: 'input-sm' %>
<%= form.text_field :severity, control_col: 'col-md-2', class: 'input-sm' %>
<%= form.text_field :priority, control_col: 'col-md-2', class: 'input-sm' %>
<%= form.collection_select :assigned_to, @users, :id, :name, control_col: 'col-md-4' , class: 'input-sm' %>
<%= form.date_field :resolved_at, control_col: 'col-md-4' , class: 'input-sm'%>
<%= form.hidden_field :owner, control_col: ' col-md-4', value: @current_user %>
<%= form.form_group do %>
<%= form.primary "Create Issue", class:'btn btn-sm btn-primary' %>
<% end %>
<% end %>
感兴趣的字段是:assigned_to-使用collection_select和:owner-用@current_user初始化。
在控制器中-到目前为止,代码是标准的
def create
@issue = Issue.create(issue_params)
respond_to do |format|
if @issue.save!
format.html { redirect_to @issue, notice: 'Issue was successfully created.' }
format.json { render :show, status: :created, location: @issue }
else
format.html { render :new }
format.json { render json: @issue.errors, status: :unprocessable_entity }
end
end
end
...和
def issue_params
params.require(:issue).permit(:summary,:description,:severity,:priority,:assigned_to, :owner,:resolved_at)
end
正如我之前提到的,此代码可通过控制台运行-添加问题记录而不会出现任何错误。但是,当我尝试通过表单提交使用它时,出现以下错误。
User(#70029712374140) expected, got "1" which is an instance of String(#47333497052640)
我已经阅读了SO的文档和类似问题,但未能找到解决方案。 :owner字段值作为User对象正确传递,但:assigned_to字段作为字符串传递。由于某种原因,红宝石魔术对我不起作用。我敢肯定这是微不足道的事,但是几天以来都没有发现错误,因此是一个问题。
任何指针将不胜感激。
TIA。
答案 0 :(得分:0)
我认为您的问题可能与某个Issue上的外键名称有关。 Issue属于一个:owner和:assigned_to,但是在用户模型中,外键也是:owner和:assigned_to -这使我相信在您的数据库中,您的问题表上有名为:owner和:assigned_to的列< / p>
将Issue对象所属的用户关联到用户的方法是使用具有诸如:owner_id和:assigned_to_id之类的ID的外键。因此,将问题表Foreign_keys从:object更改为:object_id,将:assigned_to更改为:assigned_to_id。表单并不是要以参数形式传递对象,而应以ID形式传递。
您的行:
<%= form.collection_select :assigned_to, @users, :id, :name, control_col: 'col-md-4' , class: 'input-sm' %>
正常工作-它为:assigned_to键创建选择选项,其中值是用户的ID,标签是名称。如前所述,我将您的数据库更改为在Issue对象上具有:assigned_to_id,然后将此行更新为:
<%= form.collection_select :assigned_to_id, @users, :id, :name, control_col: 'col-md-4' , class: 'input-sm' %>
然后,您的Issue对象上也会有一个:owner_id,因此您的hidden_field应该更改为:
<%= form.hidden_field :owner_id, control_col: ' col-md-4', value: @current_user.id %>
(请注意,如果@current_user可能为零,则用@current_user.id
替换@current_user.try(:id)
)
您需要将控制器中的strong_params更新为:
def issue_params
params.require(:issue).permit(:summary,:description,:severity,:priority,:assigned_to_id, :owner_id,:resolved_at)
end
最后,如果将这些列更改为:owner_id和:assigned_to_id,则需要更新User模型以具有以下关系:
has_many :issues_owned, :class_name => 'Issue', :foreign_key => 'owner_id'
has_many :issues_assigned, :class_name => 'Issue', :foreign_key => 'assigned_to_id'
答案 1 :(得分:0)
更改后,我能够保存记录。
我浏览了我的控制台脚本,意识到我的工作示例中的字段也带有“ _id”。我误认为它按原样工作。
总是以为,这是微不足道的。
感谢@armont_development。给出的解释为我清除了许多指示。