collection_select 在 ROR 形式中将值作为字符串传递并且不保存

collection_select in ROR form passes value as string and does not save

我正在尝试使用 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

添加 Issue 的表单代码 -

  <%= 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 字段值作为用户对象正确传递,但 :assigned_to 字段作为字符串传递。出于某种原因,ruby 魔法对我不起作用。我确信这是微不足道的事情,但几天以来我无法找到错误,因此出现了这个问题。

如有指点,我们将不胜感激。

TIA。

我认为您的问题可能与您在 Issue 上的外键名称有关。一个问题 belongs_to 一个 :owner 和一个 :assigned_to 但是在用户模型中外键也是 :owner 和 :assigned_to ——这让我相信在你的数据库中你有关于您的问题的名为 :owner 和 :assigned_to 的列 table

将 Issue 对象 belongs_to 与用户相关联的方法是使用 foreign_keys 像 :owner_id 和 :assigned_to_id 这样的 ID。因此,将您的问题 table 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 键创建 select 选项,其中值是用户的 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,那么您需要更新您的用户模型以具有这些关系:

    has_many :issues_owned, :class_name => 'Issue', :foreign_key => 'owner_id'
    has_many :issues_assigned, :class_name => 'Issue', :foreign_key => 'assigned_to_id'    

我可以在进行以下更改后保存记录。

  1. 在控制器中更改 issue_params 以引用 :assigned_to_id 和 :owner_id
  2. 将分配给的表单字段更改为:assigned_to_id 并将所有者更改为:owner_id

我浏览了我的控制台脚本并意识到我的工作示例也有字段的“_id”。我误以为它按原样工作。

一直认为,这是微不足道的。

谢谢@armont_development。给出的解释为我清除了很多指针。