我搭建了一个简单的例子来说明我遇到的问题。 在这个例子中,我有一个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
飞船/ _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)
我看到我的飞行员在哈希中被发送为一个字符串,但我似乎并没有找到我应该如何做到这一点。
答案 0 :(得分:5)
使用集合选择并仅返回导频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|
...
答案 1 :(得分:1)
您有一对一的可选关系。只列出所有飞行员都可以覆盖它们。创建一个新的飞行员比从整个列表中分配一个更好。
如果您想使用,请尝试使用此代码。请记住,如果您想转移飞行员,也可以使用下面的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
希望这会有所帮助......
答案 2 :(得分:0)
只需将以下代码替换为您的代码,您就可以了。
<%= f.label :pilot %>
<%= f.select :pilot, Pilot.all.map{ |p| [p.name, p.id] } %>
这将在选择下拉列表中显示飞行员姓名,并在保存时保存特定飞行员的ID。