简体   繁体   中英

Complex Search with Multiple Models and Geokit using Rails

I am attempting to make a search very complicated (of course, to make it easier for users)

I've got an app with 3 models: Campaigns, Businesses and Locations

like so:

\\ campaign.rb
  belongs_to :business
  has_many :locations, :through => :business
  acts_as_mappable

\\ business.rb
  has_many :campaigns
  has_many :locations

\\ location.rb
  belongs_to :business
  has_many :campaigns, :through => :business
  acts_as_mappable

The way this is set up, there are some businesses that have multiple locations. For those that don't, the geokit info is coded into the campaign database entry. For those that do have multiple locations the geokit info is coded into the location database entry.

I am trying to do a search for campaigns that will return the results within a certain distance. This is simple enough when dealing with businesses that have a single address.

  Campaign.find(:all,  
       :conditions => [blahblahblah],
       :origin => address,
       :within => distance
       )

However, I want to also include campaigns that belong to businesses that have multiple locations. I want the search to return a result for that campaign, if the business has multiple locations, and if any of those locations fall within the bounds. I was thinking something like:

  Campaign.find(:all, 
       :include => [:business, :locations]
       :conditions => [blahblahblah],
       :origin => address,
       :within => distance
       )

But this doesn't return any results for campaigns that belong to businesses that have multiple locations. I'm a noob when it comes to SQL so I'm not exactly sure how to have rails search in one model (Campaign), and search across another model (the Business model) to grab results from the Location model. The fact that geokit is involved makes it even more complex.

I tried: acts_as_mappable :through => :locations in the campaign.rb but it just threw an sql error

I messed around with a polymorphic model "addressable" but I found I would pretty much have to start from the ground up on the controllers of the other models.

I've also thought about named_scopes but I believe that geokit does not support them.

Any suggestions?

If you think your model is overly complicated its a good sign that it needs a redesign.

Is it possible to have a campaign without a business? if not, then it doesnt make sense to make campaign act_as_mappable (Im assuming your campaign DB has lat and lng columns) if business already has mappable locations.

If campaign is associated with a business that has multiple locations, whats considered location of the campaign? What do you store in campaigns.lat and lng attributes?

If youre sticking with your datamodel, I recommend to break up your search into multiple commands:

def find_campaigns_near(origin,distance)
    locations = Location.find(:all,  
            :origin => address,
            :within => distance
    );
    # use Hash for uniqueness based on id
    campaigns = Hash.new
    locations.each do |location|
        location.campaigns.each do |campaign|
            campaigns[campaign.id] = campaign if campaigns[campaign.id].blank?
        end
    end
    campaigns
end

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