很抱歉问了一个初学者的问题。我无法获得"collection_select"在特定情况下工作。
我正在尝试基于以下模型编写一个简单的Rails3.1应用程序:
class Site < ActiveRecord::Base
has_many :supply_sites, :dependent => :destroy
has_many :demand_sites, :dependent => :destroy
accepts_nested_attributes_for :supply_sites
accepts_nested_attributes_for :demand_sites
end
class DemandSite < ActiveRecord::Base
belongs_to :site, :class_name => "Site"
has_many :translinks , :dependent => :destroy
end
class SupplySite < ActiveRecord::Base
belongs_to :site, :class_name => "Site"
has_many :translinks , :dependent => :destroy
end
class Translink < ActiveRecord::Base
belongs_to :supply_site, :class_name => "SupplySite"
belongs_to :demand_site, :class_name => "DemandSite"
end
迁移如下:
class CreateSites < ActiveRecord::Migration
def self.up
create_table :sites do |t|
t.string :name
t.string :codename, :limit => 3
t.timestamps
end
end
def self.down
drop_table :sites
end
end
class CreateSupplySites < ActiveRecord::Migration
def self.up
create_table :supply_sites do |t|
t.integer :site_id
t.float :supply_quantity
t.timestamps
end
end
def self.down
drop_table :supply_sites
end
end
class CreateDemandSites < ActiveRecord::Migration
def self.up
create_table :demand_sites do |t|
t.integer :site_id
t.float :demand_quantity
t.timestamps
end
end
def self.down
drop_table :demand_sites
end
end
class CreateTranslinks < ActiveRecord::Migration
def self.up
create_table :translinks do |t|
t.integer :supply_site_id
t.integer :demand_site_id
t.float :unit_cost
t.float :quantity
t.timestamps
end
end
def self.down
drop_table :translinks
end
end
我希望能够在从下拉菜单中选择"供应站点"one_answers"需求站点"各个供应站点或需求站点的代码名称,其中代码名称被指定为"站点"。
当添加新的"供应站点"(或"需求站点")时,以下操作效果良好(来自"_form.html.erb",适用于供应站点或需求站点。
<div class="field">
<%= f.label :site_id %><br />
<%= f.collection_select :site_id, Site.find(:all), :id, :codename %>
</div>
现在我想要一些类似的东西来添加一个新的"Translink"连接供应站点和需求站点。我不想添加相应的supply_site_id或demand_site_id手动,但要根据基础站点中定义的代号选择一个需求站点。我可以做以下操作以获得下拉菜单来选择,比如说,从现有的供应站点中选择一个:
<div class="field">
<%= f.label :supply_site_id %><br />
<%= f.collection_select :supply_site_id, SupplySite.find(:all), :id, :id %>
</div>
然而,与其在下拉菜单中显示供应站点的id,我更愿意查看底层"站点"的代号并从中进行选择。
<div class="field">
<%= f.label :supply_site_id %><br />
<%= f.collection_select :supply_site_id, SupplySite.find(:all), :id ,????? %>
</div>
我该怎么做?
如有任何帮助,我们将不胜感激!
Stefan
检查formbuilder api中的fields_for
方法。它允许你做一些类似的事情来处理嵌套属性:
<%= f.fields_for(options) do |nested_f|
nested_f.text_field :nested_attribute
谢谢Katen!
解决方案是向需求站点类和供应站点类添加一个方法,如下所示:
class SupplySite < ActiveRecord::Base
belongs_to :site, :class_name => "Site"
has_many :translinks , :dependent => :destroy
accepts_nested_attributes_for :translinks
def supply_site_codename
self.site.codename
end
结束
class DemandSite < ActiveRecord::Base
belongs_to :site, :class_name => "Site"
has_many :translinks , :dependent => :destroy
accepts_nested_attributes_for :translinks
def demand_site_codename
self.site.codename
end
end
通过这种方式,我可以使用标准的"collection_select",并引用下面的"站点"的代码名:
<div class="field">
<%= f.label :supply_site_id %>
<br/>
<%= f.collection_select :supply_site_id, SupplySite.find(:all), :id, supply_site_codename %>
</div>
<div class="field">
<%= f.label :demand_site_id %>
<br/>
<%= f.collection_select :demand_site_id, DemandSite.find(:all), :id, :demand_site_codename %>
</div>
现在它按要求工作。关键是要定义一种方法来引用相应的站点模型。
Stefan