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 sin开发者_开发技巧gle 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
精彩评论