Vitor Pamplona

Innovation on Vision: Imaging , Enhancement and Simulation

Rails: Múltiplos modelos, um form

Dica rápida. Imagine que você tenha uma composição chamada Carro, conforme abaixo:

class Carro < ActiveRecord::Base  
has_one :Motor
has_one :Lataria

...
end

class Motor < ActiveRecord::Base
belongs_to :Carro
...
end

class Lataria < ActiveRecord::Base
belongs_to :Carro
...
end

na qual, mapeada para o banco de dados, torna-se:

create_table :carros do |t|  
t.column :nome, :string, :limit => 60
t.column :marca, :string, :limit => 60
t.column :placa, :string, :limit => 10
end

create_table :latarias do |t|
t.column :marca, :string, :limit => 60
t.column :modelo, :string
t.column :cor, :string, :limit => 20
end

create_table :motores do |t|
t.column :marca, :string, :limit => 60
t.column :modelo, :string
t.column :potencia, :string
end

Imagine que o seu formulário de cadastro de carros possibilite a inclusão direta de motores e latarias. Ou seja, um único formulário pedirá todas estas informações e as incluirá no banco de dados. Como construir a view de modo que o Rails, preencha os valores na mesma estrutura que os objetos e torne o código tão intuitivo quanto isto?

def create  
if request.post?
@carro = Carro.new(params[:carro])
@carro.Lataria = Lataria.new(params[:lataria])
@carro.Motor = Motor.new(params[:motor])
@carro.save
end
end

Simples: Usando fields_for dentro de seu form_for:

<% form_for :carro, :url => { :action => :create } do |c| %>  
Nome: <%= c.text_field :nome %><br/>
Marca: <%= c.text_field :marca %><br/>
Placa: <%= c.text_field :placa %><br/>

<% fields_for :lataria do |l| %>
Marca: <%= l.text_field :marca %><br/>
Modelo: <%= l.text_field :modelo %><br/>
Cor: <%= l.text_field :cor %><br/>
<% end %>

<% fields_for :motor do |m| %>
Marca: <%= m.text_field :marca %><br/>
Modelo: <%= m.text_field :modelo %><br/>
Potência: <%= m.text_field :potencia %><br/>
<% end %>

<%= submit_tag %>
<% end %>

O formulário é baseado em Carro, portanto chamará

Carro::create 

e o

@carro.save 

salvará também a nova lataria e o novo motor.

Para o update (edit), o fields_for deve ser criado para o objeto, e não para a classe, como foi feito no create .

<% form_for (@carro), :url => { :action => :update } do |c| %>  
Nome: <%= c.text_field :nome %><br/>
Marca: <%= c.text_field :marca %><br/>
Placa: <%= c.text_field :placa %><br/>

<% fields_for @carro.lataria do |l| %>
Marca: <%= l.text_field :marca %><br/>
Modelo: <%= l.text_field :modelo %><br/>
Cor: <%= l.text_field :cor %><br/>
<% end %>

<% fields_for @carro.motor do |m| %>
Marca: <%= m.text_field :marca %><br/>
Modelo: <%= m.text_field :modelo %><br/>
Potência: <%= m.text_field :potencia %><br/>
<% end %>

<%= submit_tag %>
<% end %>

Desta forma no controller, temos:

def update
@carro = Carro.find(params[:id])
@carro.motor.update_attributes(params[:motor])
@carro.lataria.update_attributes(params[:lataria])
respond_to do |format|
if @juridica.update_attributes(params[:juridica])
format.html { redirect_to(@carro) }
else
format.html { render :action => "edit" }
end
end
end

Posted in Feb 21, 2008 by Vitor Pamplona - Edit - History

Showing Comments

Interessante. Mas, sinceramente, prefiro (e uso) outra abordagem, que simplifica ainda mais o controller, movendo mais codigo para o modelo - vale uma olhada: http://pivots.pivotallabs.com/users/nick/blog/articles/270-creating-multiple-models-in-one-action

(nesse caso, bastaria aninhar os fiels_for, criar os metodos motor_attributes etc em Carro, e fazer @ carro = Carro.new (params [: carro]); @ carro.save no controller.

- - Bruno

- - Posted in Feb 18, 2008 by 201.40.138.91

:)

Por isso que to gostando do Rails. Sempre tem um jeito melhor de fazer as coisas.

- - Vitor Pamplona

- - Posted in Feb 19, 2008 by 189.27.242.21

Olá, gostei muito do tuto, deu tudo certo aqui, só tenho uma pergunta, tenho um campo do formulário que pertence ao outro model " carro.lataria " que é imagem " lataria.foto " e tou usando o plugin " file_column ", mas não envi nem atualiza a imagem, vc saberia como faço o upload de imagem para o modelo lataria pelo formulario do carro?

- - Hamilton

- - Posted in Aug 24, 2009 by 189.33.14.118

Add New Comment

Your Name:


Write the code showed above on the text below.