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| %>
Cidade onde se localiza a instituição<%= f.label :cidade %> <%= f.collection_select :city_id, @cities, :id, :nome, include_blank: true %> (to be included later)
State index template:
Selecione um estado
<% @states.each do |s| %> <% end %><%= s.sigla %> | <%= s.nome %> | <%= button_to 'Selecionar', institution_selstate_path( s ) %> |
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