简体   繁体   中英

Rails 4 collection_select from another model

My model has the following (relevant) declartions:

class Campaign < ActiveRecord::Base
  has_many :placements, dependent: :destroy
  has_many :clients, dependent: :destroy

  accepts_nested_attributes_for :clients, allow_destroy: true
  accepts_nested_attributes_for :placements, allow_destroy: true
end

class Placement < ActiveRecord::Base
  has_one :client, through: :campaign
  belongs_to :campaign
  validates_presence_of :hashtags_instagram, :hashtags_twitter, :sms, :url, :channel
end

class Client < ActiveRecord::Base
  belongs_to :campaign
  belongs_to :placement

  validates_presence_of :client_name
end

So effectively, campaigns have many placements and clients. Placements have exactly one client, and are associated with exactly one campaign (or at least should be, I'm still not sure I did that correctly).

So in my placement form, I want it to display a dropdown menu of all of the clients belonging to the placement's campaign (not all campaigns). If it is a new placement, it should display "Please Select or similar", otherwise, it should display the client belonging to that placement.

I can't seem to get the :prompt option to work though. It never actually displays a Please Select, just the first client in the list. I was attempting to use this to get it to work:

Oddly, if I change prompt to include_blank, it does actually show the blank item (although it still selects the first client in the list, not the blank item).

When I tried some things, I tried the code:

 = f.collection_select(:placement_id, @placement.client.all.to_a, :id, :client_name, {:prompt => true}, class: "newdropdown-menu", id: "newdropdown")

And got the error message:

Could not find the source association(s) :client or :client in model Campaign. Try 'has_many :client, :through => :campaign, :source => <name>'. Is it one of :user, :placements, :clients, or :photo?

If I change the collection select to read:

= f.collection_select(:campaign_id, @placement.campaign.clients.all.to_a, :id, :client_name, {:prompt => true}, class: "newdropdown-menu", id: "newdropdown")

Then it runs, but does not actually display the prompt, just the list.

Changing @placement to placement does not seem to have any effect (which seems odd).

I don't want to change it to has_many, since placements should have exactly one client. How should I proceed? I tried messing with :source, but it doesn't seem to relate to my problem.

You need to place you html options in a hash:

f.collection_select(:campaign_id, @placement.campaign.clients.all, :id, :client_name, {:prompt => true}, {class: "newdropdown-menu", id: "newdropdown"})

Documentation available here: http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM