Problemas rails 3.2 e fields_for

3 respostas
apoklypse

Tenho os seguintes modelos

class Mantenedora < ActiveRecord::Base
  validates_presence_of :nome,:sigla,:cnpj,:telefone, :message => "não pode ser branco"
  #validates_numericality_of :cnpj,:telefone,  :message => "pode ser somente numero"
  validates_length_of :cnpj, :within => 14..18,  :message => "deve ter 14 caracteres"
  validates_length_of :telefone, :within => 10..14,  :message => "telefone com DDD"
  belongs_to :endereco
  #accepts_nested_attributes_for :endereco, :allow_destroy => true
  #attr_accessible :endereco_attributes
end



class Endereco < ActiveRecord::Base
  
  belongs_to :tipo_endereco
  belongs_to :tipo_logradouro
  has_one :mantenedora
  #belongs_to :mantenedora, :class_name => "Mantenedora", :foreign_key => "mantenedora_id"
end

Tenho a seguinte View de cadastrar Mantenedora

<%= form_for(@mantenedora) do |f| %> <% if @mantenedora.errors.any? %> <div id="error_explanation"> <h2><%=
pluralize(@mantenedora.errors.count, "error") %> Mantenedora não pode ser salva:</h2>

 <ul> <% @mantenedora.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>

 <fieldset> <legend>Cadastro de Mantenedora:</legend> <div class="cadastro"> <%= f.label :nome %>:

 </div> <div class="cadastro"> <%= f.text_field :nome %>

 </div> <div class="cadastro"> <%= f.label :sigla %>:

 </div> <div class="cadastro"> <%= f.text_field :sigla %>

 </div> <div class="cadastro"> <%= f.label :cnpj %>:

 </div> <div class="cadastro"> <%= f.text_field :cnpj ,:class=> 'cnpj' %>

 </div> <div class="cadastro"> <%= f.label :telefone %>:

 </div> <div class="cadastro"> <%= f.text_field :telefone , :class=> 'telefone'%>

 </div>

 		<%= f.fields_for :endereco, @mantenedora.endereco do |endereco_form| %>
		  <%= render :partial => 'endereco', :locals => { :l => endereco_form }  %>
		<% end %>


 <div class="actions"> <%= f.submit %> <%= link_to '', mantenedoras_path, :class => 'voltar' %>

 </div> </fieldset>

<% end %>

Minha situação é a seguinte, tenho uma tabela Mantenedora que tem a coluna endereco_id que é chave estrangeira da tabela Endereco, que ao cadastrar mantenedora, quero cadastrar o endereço também(estou usando uma tabela a parte pois terei vários cadastros que precisam do endereco assim fica com menos replicações), estou usando fields_for para carregar os dados do cadastro do endereco, porém aparece esse erro ao salvar a mantenedora:

Endereco(#2112) expected, got ActiveSupport::HashWithIndifferentAccess(#2100) Rails.root: /Users/maxmiller/github/sistemico

Application Trace | Framework Trace | Full Trace
app/controllers/mantenedoras_controller.rb:45:in `create'
Request

Parameters:

{"utf8"=>"✓",
"authenticity_token"=>"RUIcrbjFPXYyh7R9EtK3S8aQmdTCkN1XHbufssB2DRw=",
"mantenedora"=>{"nome"=>"yyyy",
"sigla"=>"yyyy",
"cnpj"=>"11.111.111/1111-11",
"telefone"=>"(77)7777.7777",
"endereco"=>{"tipo_endereco_id"=>"1",
"tipo_logradouro_id"=>"2",
"logradouro"=>"xxxxx",
"numero"=>"100000",
"complemento"=>"jdhfgsd",
"bairro"=>"dgkfhds",
"cep"=>"[telefone removido]"}},
"commit"=>"Cadastrar Mantenedora"}

3 Respostas

ricardo.valeriano

Tudo bem apoklypse?

Cara, descomenta o “accepts_nested_attributes_for :endereco” na sua classe Mantenedora.

No erb, troca o:

Por

Deve ser o suficiente.

Agora só uma opinião (estou de fora e não conheço o modelo de negócios que você está resolvendo), me parece que faz mais sentido uma relação onde o endereço pertence a mantenedora. Mas como eu disse, vai depender do que você está modelando por aí.

Faz os testes e qualquer dúvida diga.

rogerio.alcantara

Olá pessoal, tudo bom?

Eu tenho um caso bem semelhante ao apoklypse:

Tenho um model Company que tem o atributo address_id. Isso ocorre porque a entidade Address também será associada com outras entidades do sistema. Segui a sugestão do amigo ricardo.valeriano, deixando o accepts_nested_attributes_for :address (o q me forçou a incluir o :address_attributes no attr_accessible) Logo, tenho:

class Company < ActiveRecord::Base
attr_accessible :address_attributes
has_one :address, :dependent => :destroy
accepts_nested_attributes_for :address, :allow_destroy => true
end

Na entidade Address eu não tenho o belongs_to :company (pois é uma tabela que será associada a outras entidades).
E na minha view, eu tenho:
<%= form_for(@company) do |f| %>

<%= render :partial => "addresses/form", :locals => {:f => f} %>
<%= f.submit %>
<% end %>
Bom, o primeiro problema, é que a partial do form do address não era exibida. Para exibi-la eu tive que iniciar a entidade address de company da seguinte forma:
class CompaniesController < ApplicationController def new @company = Company.new @company.address = Address.new end end
Resolvido isso, ao submeter o form, é disparada a seguinte exception:
unknown attribute: company_id app/controllers/companies_controller.rb:44:in `new' app/controllers/companies_controller.rb:44:in `create' ..... Parameters:

{“utf8”=>“✓”,
“authenticity_token”=>“0XTnRdWKx3MSEzEfofoxFgNR8iLzs16rKWWSAZGX9GI=”,
“address_attributes”=>{“address”=>"",
“complement”=>"",
“zipcode”=>"",
“city_id”=>""}},
“commit”=>“Create Company”}


Ok, eu estou entendendo q o Rails está tentando setar um atributo company_id na entidade Address.

Alguém saberia qual seria a configuração adequada dos Modelos para atender esse cenário?

Espero ter me feito entender…

Valeu pessoal!

renatoramiro

No teu controller faz assim:

class CompaniesController < ApplicationController
  def new
    @company = Company.new
    address = @company.build_address
  end
end
Criado 5 de fevereiro de 2012
Ultima resposta 7 de fev. de 2013
Respostas 3
Participantes 4