0

Sorry for this newbie question but I cannot figure how I can do this..

I have the following City table

# Table name: cities
#
#  id          :integer
#  name        :string(255)
#  country     :string(255)

(note: I am not using a separate Country table as I use Geokit-rails and think it is simpler to store all Google queries in the same table. However It would be easier to have separate tables to render what I want through a belong_to/has_many association)

In my city/index view I want to loop all the cities for each countries in order to render something like:

United States
  New York
  San Francisco
  Los Angeles
United Kingdom
  London
Spain
  Madrid
...

By now, What I can get is what it provided by scaffolding

Model

def index
  @cities = City.all
end

View

<table>
  <% for city in @cities %>
  <tr>
    <th><%= city.country %></th>    
  </tr>
  <tr>
    <td><%= city.name %></td>
  </tr>
    <% end %>
</table>

Rendering:

United States
  Los Angeles
United States
  New York
...

I didn't find any resource about this. I would be pleased if someone could help me (I don't know with which I have to start: find_by_ /params /each or collection?)

Thanks a lot!

3 Answers 3

3

The correct way to do this is to create a Country table with id and name and in your City model just keep a country_id to the country, instead of a string

so

class Country < ActiveRecord::Base
  has_many :cities
end

class City < ActiveRecord::Base
  belongs_to :country
end

then you can call Country.includes(:cities) and iterate over them like this in your view:

<% for country in countries %>
  <%= country.name %>
  <% for city in country.cities %>
    <%= city.name %>
  <% end %>
<% end %>

If you still want to use your way, you could do something like

@cities = City.order("country asc")
@countries = @cities.map(&:country).uniq!

<% for country in @countries %>
  <%= country.name %>
  <% for city in @cities %>
    <%= city.name if city.country == country %>
  <% end %>
<% end %>
Sign up to request clarification or add additional context in comments.

Comments

1

I've had success with the group_by method:

@cities.group_by(&:country).each do |country, cities|
  puts country.name
  cities.each do |city|
    puts "-> #{city.name}"
  end
end

Output:

United States
-> New York
-> San Francisco
-> Los Angeles
United Kingdom
-> London
Spain
-> Madrid
-> Barcelona

Of course, you'll probably be doing this in an erb template, but the idea is the same:

<ul>
    <% @cities.group_by(&:country).each do |country, cities| %>
        <li><%= country.name %></li>
        <li>
            <ul>
                <% cities.each do |city| %>
                    <li><%= city.name %></li>
                <% end %>
            </ul>
        </li>
    <% end %>
</ul>

Output:

  • United States
    • New York
    • San Francisco
    • Los Angeles
  • United Kingdon
    • London
  • Spain
    • Madrid
    • Barcelona

Comments

0

The official rails guides are an excellent place to start ;)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.