预期模型(#...),使用 select 标签时出现字符串(#...)错误

Model(#...) expected, got String(#...) error when using select tag

我搭建了一个简单示例来说明我遇到的问题。 在这个例子中,我有一艘 Starship 和一艘 Pilot。我希望能够在创建时将现有飞行员分配给星际飞船。

starship.rb

class Starship < ApplicationRecord
  has_one :pilot

  validates :name, presence: true
end

pilot.rb

class Pilot < ApplicationRecord
  belongs_to :starship, optional: true

  validates :name, presence: true
end

starships/_form.html.erb

<div class="field">
  <%= f.label :pilot %>
  <%= f.select :pilot, Pilot.all %>
</div>

starships_controller.rb

  def starship_params
    params.require(:starship).permit(:name, :pilot)
  end

参数散列

{"name"=>"Nostromo", "pilot"=>"#<Pilot:0x007f85ff547f90>"}

我收到这个错误

Pilot(#70106745549840) expected, got String(#70106709663840)

我看到我的 pilot 是作为散列中的字符串发送的,但我似乎没有找到我应该如何做的其他方式。

仅使用集合 select 和 return 飞行员 ID。

<%= f.collection_select(:pilot_id, Pilot.all, :id, :name) %>

请注意,您需要更改 starship_params

  def starship_params
    params.require(:starship).permit(:name, :pilot_id)
  end

为 :pilot_id

添加 attr_accessor
class Starship < ApplicationRecord
  attr_accessor :pilot_id

修改你的创建如下...

def create
  @starship = Starship.new(starship_params)
  @starship.pilot = Pilot.find(@starship.pilot_id)
  respond_to do |format|
    ...

你们有一对一的可选关系。只需列出所有飞行员即可覆盖它们。创建一个新的飞行员比从整个列表中分配一个更好。

不过,如果您想使用,请尝试使用此代码。请记住,如果您想转移飞行员,也可以使用下面的 Pilot.pluck(:id)

<div class="field">
  <%= f.label :pilot_id %>
  <%= f.select :pilot_id, Pilot.where('starship_id is NULL').pluck(:id) %>
</div>

现在在您的 starship_controller 创建方法中 写

def create
    @starship = Starship.new(starship_params)
    pilot = @starship.build_pilot
    pilot.id= params[:starship][:pilot_id]
    pilot.reload
    respond_to do |format|
      if @starship.save
        format.html { redirect_to root_path, notice: 'Starship successfully created.' }
       else
         format.html { redirect_to root_path, notice: 'Error occured.' }
       end
end

你的强参数应该是

def starship_params
    params.require(:starship).permit(:name, :pilot_id)
end

希望这对您有所帮助...

Just replace below code with your code and you are good to go.

<%= f.label :pilot %>
<%= f.select :pilot, Pilot.all.map{ |p| [p.name, p.id] } %>

这将在 select 下拉列表中显示飞行员的姓名,并在保存时保存特定飞行员的 ID。