Newbie question, "show items in selected city and category"


#1

Hi,
rails newbie needs help :slight_smile:

I have classified ads (cads) related with cities and categories:

class Cad < ActiveRecord::Base
has_and_belongs_to_many :categories
has_and_belongs_to_many :cities
end

class Category < ActiveRecord::Base
has_and_belongs_to_many :cads
end

class City < ActiveRecord::Base
has_and_belongs_to_many :cads
end

I assume that user can act such way: first, from cities listing, which
is produced by ‘list’ method in cities_controller, the user chooses
city ( clicks on ‘show’ link).

cities_controller#show contains the following:
def show
@city = City.find(params[:id])
@cads = @city.cads
@categories_of_cads_in_city = @cads.map {|cad|
cad.categories}.flatten.uniq
end

So, the user sees classified ads and categories of these ads:

cities/show.rhtml:
[…]
<% @cads.each do |cad| %>
<%=link_to cad.title,
:controller => “cads”,
:action => “show”,
:id => cad.id
%>

<% @categories_of_cads_in_city.each do |category| %>
<%= link_to category.name,
:controller => “categories”,
:action => “show”,
:id => category.id
%>
[…]

The next thing user may want to do - see classified ads in some
category of chosen city (assume in “Health” category) , so he clicks on
link “Health”.
So i must find ads which are associated with chosen city and category
“Health”. How can i do achieve this ??
Thanks


#2

ogurec wrote:

has_and_belongs_to_many :cads

end

So i must find ads which are associated with chosen city and category
“Health”. How can i do achieve this ??

This is untested, and there may be an easier way, but this should work:

class Cad
def self.with_category_and_city(category, city)
with_scope :find => {:conditions => [“categories.id = ? AND
cities.id = ?”, category.id, city.id], :include => [:categories,
:cities]} do
yield
end
end

def self.find_by_category_and_city(category, city, *args)
with_category_and_city(category, city) { find(*args) }
end
end

Set up like this, the Cad.find_by_category_and_city method will take
standard ActiveRecord::Base.find options.

Example:
Cad.find_by_category_and_city(@category, @city, :first)
Cad.find_by_category_and_city(@category, @city, :all, :order =>
“cads.name”)

Dan M.


#3

Many thanks Dan,
i’ve added method ‘category’ into ‘cities_controller’ and its works!

I understand how @category gets its value regarding passed id, but how
can i get the value of @city that was previously set in
cities_controller#show ?

cities_controller#category
@city = City.find(1)
@category = Category.find(params[:id])
@cads = Cad.find_by_category_and_city(@category, @city, :all)


#4

Thanks a lot!


#5

ogurec wrote:

@cads = Cad.find_by_category_and_city(@category, @city, :all)
I would pass both the ID for the city and the ID for category to your
‘category’ action.

Example, in the /cities/show view:
<% for category in @categories %>
<%= link_to h(category.name), :action => ‘category’, :id => @city,
:category => category %>
<% end %>

The with the default routes the URL will be like:
/cities/category/1?category=3
And then in the controller for that action:
@city = City.find(params[:id])
@category = Category.find(params[:category])

Dan M.