How to load a selection list into the method new of a controller?

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 = ‘So
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 instituio
Estado selecionado: <%= @estado_selecionado %> <%= link_to "Selecionar estado...", states_path %>
<%= f.label :cidade %> <%= f.collection_select :city_id, @cities, :id, :nome, include_blank: true %> (to be included later)
<% end %>

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 :slight_smile: .
Is my approach correct?
Any help will be very appreciated. Sorry my bad english!
Thanks in advance!

Luis

On 28 May 2012 04:37, LuisRuby [email protected] wrote:

Table name: countries

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

That is not right, a cities country is accessible through the state
via @city.state.country.

belongs_to :state
end

== Schema Information

Table name: cities

id :integer not null, primary key

country_id :integer not null

Above is not needed.

I have not even read the rest, you have provided much too much
information. If you still have a problem then simplify it down to to
the smallest amount of code that demonstrates it and post that.

Colin

On 28 May 2012 13:58, LuisRuby [email protected] wrote:

Thank you for your fast reply!
Yes, I agree it isn’t necessary to put a direct relation to country inside
the city model. But I did it because sometimes the user will not know to
which state a new city belongs to, and at least he will know the country.

With it in you could get into a situation where @city.country is not
the same as @city.state.country. Also note that @country.cities will
only include those accessed via state.

Please don’t top post, it makes it difficult to follow the thread.
Insert you reply at appropriate points in the previous message.
Thanks.

Colin

Thank you for your fast reply!
Yes, I agree it isn’t necessary to put a direct relation to country
inside
the city model. But I did it because sometimes the user will not know to
which state a new city belongs to, and at least he will know the
country.

Luis

Em segunda-feira, 28 de maio de 2012 03h27min39s UTC-3, Colin L.
escreveu:

Em segunda-feira, 28 de maio de 2012 00h37min14s UTC-3, LuisRuby
escreveu:

== Schema Information

== Schema Information

end

== Schema Information

State.create!(country_id: Country.find(:first, conditions: "sigla =
nome: ‘Cianorte’)
routes.rb:
/states/index(.:format) states#index
Institution new template:
(to be

<%= s.sigla %>
end
else
end
receive the same screen before the state selection. I have many similar
situations in my system… all waiting for this solution :slight_smile: .
Is my approach correct?
Any help will be very appreciated. Sorry my bad english!
Thanks in advance!

Luis

Hmmmm, I didn’t think in this situation… you are right. I will exclude
country_id from de city model.
Well. Filtering my models to simplify the explanation of my problem, I
end
up with these:

class State < ActiveRecord::Base
has_many :cities
has_many :institutions, :through => :cities
belongs_to :country
end

class City < ActiveRecord::Base
has_many :institutions
belongs_to :state
end

class Institution < ActiveRecord::Base
belongs_to :city
end

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!(state_id: State.find(:first, conditions: “nome =
‘desconhecido’”).id, nome: ‘desconhecida’)
City.create!(state_id: State.find(:first, conditions: “nome =
‘Paran’”).id, nome: ‘Cianorte’)
City.create!(state_id: State.find(:first, conditions: “nome = ‘So
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

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| %>


Estado selecionado: <%= @estado_selecionado %>
<%= link_to “Selecionar estado…”, states_path %>

<%= f.label :cidade %>
<%= f.collection_select :city_id, @cities, :id, :nome,
include_blank:
true %>

<% end %>

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.all
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. Is my approach
correct?

Thanks!
Luis