简体   繁体   中英

has_many through association, and multiple search criteria, how can i make this work?

I'm trying to create a multi criteria search form. I want to submit all of the pieces of the search via GET and if they have a value assigned I would like them evaluated. The thing that I'm having trouble grasping is building a query that will allow me to layer more queries on top when you're doing it with a through association.

Just to give you an idea of how my models are set up:

class Client < ActiveRecord::Base
  has_many :campaigns
  has_many :pieces, :through => :campaigns
end

class Campaign < ActiveRecord::Base
  belongs_to :client
  has_many :pieces
end

class Piece < ActiveRecord::Base
  belongs_to :client
end

Now, with that model in mind, I'm using the collect method to grab the pieces that have an organization in common.

if params.has_key?(:criteria)
    @selected_client = Client.where(:organization => "Org1")
    @pieces = @selected_client.collect{ |c| c.pieces }.flatten
end

Is there some way of formatting that query string so that I can narrow @pieces down, a couple more times? Let's say I wanted to use that through association again, to get pieces that have another of the same Client criteria...

Thanks a ton! My brain is a pretzel at this point.

I'm not sure if i undestand very well what you're trying to do. If you want to get all pieces matching your client criteria, in rails 3, you can do this :

@pieces = Piece.joins(:campaign => :client).where(:clients => {:organization => criteria})

to get all pieces belonging to clients from organization "Org1".

You can stack as many where statements as you want to add new conditions, as @Andrew said. See this for more information .

Your first paragraph got cut off, just FYI.

If @pieces is an array, you can use a find block to narrow your search further. Although this will put the load on your server CPU rather than the SQL database.

You can stack where statements and Rails will automatically create a single query for you. Here is some sample code from the app store section of our website:

@platform = params[:platform]
@category = params[:category]
@search   = params[:app_q]

# Get initial SQL, narrow the search, and finally paginate
@apps = App.live

@apps = @apps.where("platform = ?", AppPlatforms.value(@platform)) if AppPlatforms.value(@platform)
@apps = @apps.where("(name LIKE ? OR description LIKE ?)", "%#{@search}%", "%#{@search}%") if @search
@apps = @apps.where("id IN(?)", @cat.apps) if @category && @cat = Category.find_by_id(@category)

@apps = @apps.paginate(:page => params[:page], :per_page => 10, :order => "name")

Instead of using collect you should be able to use @selected_client.pieces.where(...) to narrow your search down via SQL.

I hope this is a point in the right direction!

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