预期模型(#...),使用 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。
我搭建了一个简单示例来说明我遇到的问题。 在这个例子中,我有一艘 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_accessorclass 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。