ruby-on-rails collection_select排除了一些选择

时间:2014-01-14 03:04:29

标签: ruby-on-rails collections

概要 我希望在使用collection_select时排除一些选择选项。例如,为给定公司(table = Companies)添加新的company_code(table = Company_Listings)时,对于交换下拉列表(table = Exchanges),仅显示未列出其给定公司的交换。也可以为公司输入选项信息(再次在table = Company_Listings上)。

更多细节。

一般 我有一个可以输入公司信息的屏幕。我允许公司在多个交易所上市。我还允许输入选项信息。例如,Broken Hill Pty在澳大利亚证券交易所(ASX)作为必和必拓以及伦敦证券交易所(LSE)在BIL上市。同样,每个交易所都可以添加多个选项 此信息存储在Companies和Company_listings表中(见下文)。

示例 - 我要做的事情 1-交易清单= ASX,LSE,AMEX,NYSE
2-公司表公司= Broken Hill Pty Ltd
3-公司_表 -    Broken Hill Pty Ltd在ASX(澳大利亚证券交易所)和伦敦证券交易所(伦敦证券交易所)上市    例如在ASX = BHP和LSE = BIL上 4-当进入BHP的公司列表页面时,我希望列出的交易所下拉列表仅显示AMEX和NYSE(即排除ASX和LSE)。

table "companies" do |t|
    t.string   "name"
    t.string   "full_name"
    t.integer  "exchange_id"

create_table "company_listings" do |t|
    t.integer  "company_id"
    t.integer  "share_number"         
    t.integer  "share_price"
 t.string   "option_name"
 t.integer  "option_strike_price"
 t.date     "option_expiration_date"
 t.integer  "exchange_id"
 t.string   "company_code" 

 table "exchanges" do |t|
  t.string   "name"
  t.string   "full_name"

从该屏幕的代码 - 我需要更改

  <%= f.hidden_field :company_id %>
  <%= content_tag :tr do %>
    <%= content_tag :td, content_tag(:span, "Listed Exchange"), 
      class: 'very_large_column' %>
    <%= content_tag :td, f.collection_select(:exchange_id, Exchange.order(:id), 
          :id, :name, {}, {class: "input-fullwidth"}), class: 'data small_column' %>   
  <% end %>
  <%= content_tag :tr do %>
    <%= content_tag :td, content_tag(:span, "Stock Code"), 
      class: 'very_large_column' %>
    <%= content_tag :td, f.text_field(:company_code, 
        class: 'small_column'), class: 'data' %>  

模型

class CompanyListing < ActiveRecord::Base
   ...
   belongs_to :company
   belongs_to :exchange
   ...
end


class Exchange < ActiveRecord::Base
   ...
   has_many :company_listings, dependent: :destroy
end

2 个答案:

答案 0 :(得分:1)

collection_select的第三个参数是集合。您可以让它根据公司ID应用一些逻辑,而不是使用Exchange.order(:id)。举个例子:

class Exchange < ActiveRecord::Base
  def self.not_listed_for_company_id(company)
    # AR scope that retrieves all exchanges that the company is NOT listed on
    # NOTE: This can be made more efficient since company.exchanges will result in additional database queries 
    Exchange.where("id not in (?)", company.exchanges.collect{|e| e.id})
  end 
end

然后,在视图中:

<%= content_tag :td, f.collection_select(:exchange_id, Exchange.not_listed_for_company_id(company), 
      :id, :name, {}, {class: "input-fullwidth"}), class: 'data small_column' %>   

答案 1 :(得分:0)

同事Tristian提供了这个答案。在视图中

<%= content_tag :td, f.collection_select(:exchange_id, Exchange.order(:id), 
          :id, :name, {}, {class: "smallish_column"}), class: 'data' %>

变为

<%= content_tag :td, f.collection_select(:exchange_id, 
          Exchange.where.not(id: @company.company_listings.where.not(company_code: nil).pluck(:exchange_id)).order(:id), 
          :id, :name, {}, {class: "input-fullwidth"}), class: 'data column' %> 

感谢 皮尔