Rails 3.1 collection_select на двух уровнях? (вложенные модели) - PullRequest
0 голосов
/ 13 января 2012

Прошу прощения за вопрос начинающего.Я не могу заставить "collection_select" работать в конкретном случае.

Я пытаюсь написать простое приложение на Rails 3.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

Я хочу иметь возможность добавить новый "translink" (транспортный канал) между "сайтом снабжения" и "сайтом спроса", выбрав его в раскрывающемся меню на основе кодовых именсоответствующего сайта снабжения или сайта спроса, где кодовые имена указаны для «сайтов».

При добавлении нового «сайта снабжения» (или «сайта спроса») хорошо работает следующее (из «_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>

Однако вместо отображения идентификатора мест снабжения в раскрывающемся меню я бы предпочел увидеть ивыберите кодовое имя базового «сайта».

<div class="field">
    <%= f.label :supply_site_id %><br />
    <%= f.collection_select :supply_site_id,  SupplySite.find(:all), :id ,????? %>
  </div>

Как я могу это сделать?

Любая помощь будет принята с благодарностью!

Stefan

Ответы [ 2 ]

0 голосов
/ 15 января 2012

Спасибо, Катен!

Оказалось, что решением было добавить метод к классу сайта спроса и классу сайта предложения следующим образом:

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

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

0 голосов
/ 14 января 2012

Проверьте метод fields_for в API formbuilder. Это позволяет вам делать что-то подобное для работы с вложенными атрибутами:

<%= f.fields_for(options) do |nested_f|
  nested_f.text_field :nested_attribute
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...