LuisRuby
unread,May 27, 2012, 11:37:14 PM5/27/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to rubyonra...@googlegroups.com
Hi friends!
I'm relatively new with Rails and I'm struggling for a long time with this problem (it should have a pattern solution but until now I didn't find it): I have the following models: Institution, City, State and Country.
class Country < ActiveRecord::Base
has_many :states
has_many :cities, :through => :states
end
# == Schema Information
# Table name: countries
# id :integer not null, primary key
# sigla :string(2) not null
# nome :string(30) not null
class State < ActiveRecord::Base
has_many :cities
has_many :institutions, :through => :cities
belongs_to :country
end
# == Schema Information
# Table name: states
# id :integer not null, primary key
# country_id :integer not null
# sigla :string(2) not null
# nome :string(40) not null
class City < ActiveRecord::Base
has_many :institutions
belongs_to :country
belongs_to :state
end
# == Schema Information
# Table name: cities
# id :integer not null, primary key
# country_id :integer not null
# state_id :integer not null
# nome :string(40) not null
class Institution < ActiveRecord::Base
belongs_to :city
end
# == Schema Information
# Table name: institutions
# id :integer not null, primary key
# city_id :integer
The table states is pre-loaded with all Brazil's states (seed):
State.create!(country_id: Country.find(:first, conditions: "sigla = 'ZZ'").id, nome: 'desconhecido', sigla: 'ZZ')
State.create!(country_id: Country.find(:first, conditions: "sigla = 'BR'").id, nome: 'Distrito Federal', sigla: 'DF')
State.create!(country_id: Country.find(:first, conditions: "sigla = 'BR'").id, nome: 'Acre', sigla: 'AC') ... and so on...
City.create!(country_id: Country.find(:first, conditions: "sigla = 'BR'").id,
state_id: State.find(:first, conditions: "nome = 'desconhecido'").id,
nome: 'desconhecida')
City.create!(country_id: Country.find(:first, conditions: "sigla = 'BR'").id,
state_id: State.find(:first, conditions: "nome = 'Paraná'").id,
nome: 'Cianorte')
City.create!(country_id: Country.find(:first, conditions: "sigla = 'BR'").id,
state_id: State.find(:first, conditions: "nome = 'São Paulo'").id,
nome: 'Campinas') ... and so on...
When I create a new institution, I have to select a city from a drop-down list. But I need to constrain this list with the state the cities belong to. So I tried this way:
routes.rb:
Application.routes.draw do
get "states/index"
resources :institutions do
post 'selstate'
end
resources :cities
resources :states, only: :index
rake routes:
states_index GET /states/index(.:format) states#index
institution_selstate POST /institutions/:institution_id/selstate(.:format) institutions#selstate
institutions GET /institutions(.:format) institutions#index
POST /institutions(.:format) institutions#create
new_institution GET /institutions/new(.:format) institutions#new
Institution new template:
<%= form_for(@institution) do |f| %>
<fieldset>
<legend>Cidade onde se localiza a instituição</legend>
<div class="field">
Estado selecionado:
<%= @estado_selecionado %>
<%= link_to "Selecionar estado...", states_path %><br />
<%= f.label :cidade %>
<%= f.collection_select :city_id, @cities, :id, :nome, include_blank: true %>
<!--%#= link_to "Incluir nova cidade", new_city_path %--> (to be included later)
</div>
<% end %>
</fieldset>
State index template:
<h3>Selecione um estado</h3>
<table>
<% @states.each do |s| %>
<tr>
<td><%= s.sigla %></td>
<td><%= s.nome %></td>
<td><%= button_to 'Selecionar', institution_selstate_path( s ) %></td>
</tr>
<% end %>
</table>
class StatesController < ApplicationController
def index
@states = State.where('nome != ?', 'desconhecido').order(:nome)
end
class InstitutionsController < ApplicationController
def new
@institution = Institution.new
if session[:state_id].nil?
session[:state_id] = State.find_by_sigla('ZZ').id
end
@estado_selecionado = State.find(session[:state_id]).nome
if @estado_selecionado == 'desconhecido'
@cities = City.all
else
@cities = City.where('state_id = ?', session[:state_id]).order(:nome)
end
respond_to do |format| ...
end
end
def create
@institution = Institution.new(params[:institution])
respond_to do |format|
if @institution.save ...
end
def selstate
session[:state_id] = params[:id]
redirect_to new_institution_path
end
end
As you can see, after select the state, I return to the Institution new action. My hope was to have a state selected and the cities list constrained to those pertaining to that state. But nothing happens. I receive the same screen before the state selection. I have many similar situations in my system... all waiting for this solution :-) .
Is my approach correct?
Any help will be very appreciated. Sorry my bad english!
Thanks in advance!
Luis