航班 -
belongs_to :departure_airport
,机场 has_many :departing_flights
。
我正在尝试在 Rails 中创建一个下拉选择表单元素
form_with
,其中每个选项的关联的 :city 值是关联上的一个属性:
查看表单代码 - Flight#index:
<%= form_with(url: flights_path, method: :get) do |form| %>
<div>
<%= form.label :departure_airport, 'Departure Airport' %>
<%= form.collection_select :departure_airport, @flights, :departure_airport_id, :departure_airport.city, prompt: 'Select Departure Airport' %>
</div>
<div>
<%= form.submit 'Search Flights' %>
</div>
<% end %>
飞控代码:
class FlightsController < ApplicationController
def index
@flights = Flight.all
end
end
航班.rb:
class Flight < ApplicationRecord
belongs_to :departure_airport, class_name: 'Airport'
validates_presence_of :departure_airport
end
机场.rb:
class Airport < ApplicationRecord
has_many :departing_flights, class_name: 'Flight', foreign_key: 'departure_airport_id'
end
我可以看到该关联正在起作用,因为 html 将实际的机场对象引用字符串显示为每个下拉选项的名称/标签。但在我的一生中,我无法让每个选项都用关联上的属性命名:
Html 呈现形式摘录:
<form action="/flights" accept-charset="UTF-8" method="get">
<div>
<label for="departure_airport">Departure Airport</label>
<select name="departure_airport" id="departure_airport"><option value="">Select Departure Airport</option>
<option value="8">#<Airport:0x00000001126f0730></option>
<option value="60">#<Airport:0x0000000112728630></option>
<option value="47">#<Airport:0x0000000112713140></option>
<option value="33">#<Airport:0x00000001126fbdd8></option>
etc ...
<option value="42">#<Airport:0x0000000112c9b568></option></select>
</div>
<div>
<input type="submit" name="commit" value="Search Flights" data-disable-with="Search Flights">
</div>
</form>
我已经尝试过机场对象的任何各种属性/列(例如
:departure_airport.name
、:departure_airport.country
),但没有一个会显示为单个选项的标签。
有人能看到我在这里做错了什么吗?
关联肯定存在模型级别,如以下 Rails 控制台对象和关联查询所示:
3.1.2 :012 > f = Flight.first
Flight Load (1.4ms) SELECT "flights".* FROM "flights" ORDER BY "flights"."id" ASC LIMIT $1 [["LIMIT", 1]]
=>
#<Flight:0x000000010280c9a8
...
3.1.2 :013 > f.departure_airport_id
=> 8
3.1.2 :014 > f.departure_airport.name
Airport Load (1.0ms) SELECT "airports".* FROM "airports" WHERE "airports"."id" = $1 LIMIT $2 [["id", 8], ["LIMIT", 1]]
=> "Bordeaux Airport"
3.1.2 :015 > f.departure_airport.city
=> "Bordeaux"
3.1.2 :016 > f.departure_airport.country
=> "France"
3.1.2:017>
:departure_airport.city
这会调用符号 city
上的 :departure_airport
方法,而不是关联。
您必须使用
Flight
模型中的属性和方法:
<%= form.collection_select :departure_airport_id, @flights,
:departure_airport_id,
:departure_airport_city
%>
class Flight < ApplicationRecord
belongs_to :departure_airport, class_name: 'Airport'
# this validation is redundant, belongs_to association is required by default
# validates_presence_of :departure_airport
# this is the same as
#
# def departure_airport_city
# departure_airport.city
# end
#
delegate :city, to: :departure_airport, prefix: true
end