views:

49

answers:

2

Hi, I'm a newbie with rad rails. I wanted to write at same time in two table from one form.

I have a table machine (with nom and role as column) and a table ipvfour (with machine_id and ip as column).

So I created in models the relation has-and-belongs-to-many.

But when I'm trying to add a new machine if failed with

unknown attribute: ip

I don't really understand why, can someone help me please ?


machine.controllers:

def create @machine = Machine.new(params[:machine])

ipvfour = @machine.ip.create(params[:ip])

respond_to do |format|

  if @machine.save && ipvfour.save

    flash[:notice] = 'Machine was successfully created.'

    format.html { redirect_to(@machine) }

    format.xml  { render :xml => @machine, :status => :created, :location => @machine }

else

format.html { render :action => "new" }

format.xml { render :xml => @machine.errors, :status => :unprocessable_entity }

end

end

end


new.html.erb (machine)

New machine

<% form_for(@machine) do |f_machine| %> <%= render :partial => 'form', :locals => { :f_machine => f_machine } %>


<%= f_machine.submit 'Create' %>

<% end %>

<%= link_to 'Back', machines_path %>


_form.html.erb (machine)

<%= f_machine.error_messages %>



<% f_machine.fields_for :ip do |f_ip| %> <%= render :partial => 'ipvfours/form', :locals => { :f_ip => f_ip } %>

<% end %>


_form.html.erb (ipvfours)

<%= f_ip.label :ip %><br /> <%= f_ip.text_field :ip %>


The page to add a machine is correclty displayed with all fields but it seems that write in db failed due to .... I hope that someone will be able ti help me.

Thanks in advance.

A: 

Hi,

EDIT:

You can edit any model in any controller if you want. There's a magic trick called accepts_nested_attributes_for (google it!)

Your code should look like:

In your Controller:

def new 
  # .... your code ....

  # create empty machine
  @machine  = Machine.new

  # add one empty ip 
  @machine.ipvfours.build

  # .... your code ....

end

def create 

  # fill machine and ipvfours directly 
  @machine = Machine.new(params[:machine])

  respond_to do |format|

    if @machine.save

      flash[:notice] = 'Machine was successfully created.'

      format.html { redirect_to(@machine) }

      format.xml  { render :xml => @machine, :status => :created, :location => @machine }

    else

      format.html { render :action => "new" }

      format.xml { render :xml => @machine.errors, :status => :unprocessable_entity }

    end

  end

end

In your view:

new.html.erb

<% form_for(@machine) do |f_machine| %>  

  <%= render :partial => 'form', :locals => { :f_machine => f_machine } %>

  <%= f_machine.submit 'Create' %>

<% end %>

<%= link_to 'Back', machines_path %>

_form.html.erb (machine)

<%= f_machine.error_messages %>

<% f_machine.fields_for :ipvfours do |f_ip| %> 
  <%= render :partial => 'ipvfours/form', :locals => { :f_ip => f_ip } %>
<% end %>

_form.html.erb (ipvfours)

<%= f_ip.label :ip %>
<br />
<%= f_ip.text_field :ip %>

In your Model:

Machine model

class Machine < ActiveRecord::Base

    has_many :ipvfours, :dependent => :destroy
    accepts_nested_attributes_for :ipvfours

end

best regards

simon

sled
one things that I don't understand it where should I add your code ??I mean that I4m using the controller of machine to write, maybe I'm wrong and I should use the ipvfours controller. How can I know whitch controller used to write ? Thanks in advance.
Goueg83460
I have extended my answer ;)
sled
Yes I just saw it. Thanks. So I do exactly what you tell me but I still have one problem:ActiveRecord::UnknownAttributeError in MachinesController#createunknown attribute: ipvfourRequest:{"machine"=>{"nom"=>"titi", "ipvfour"=>{"ip"=>"10.1.1.12"}, "role"=>"dev"}, "commit"=>"Create", "authenticity_token"=>"sEoGE2dQUlq6fPL05fTl7Whr2WYWYa34dedi/uc59sI="}One think that is strange is the request that is done in wrong order while I'm filling nom and role and ip.Thanks again for your help
Goueg83460
Check this line in your machine _form.html.erb: <% f_machine.fields_for :ipvfours do |f_ip| %> are you sure you DID write :ipvfours (plural!!) seems like you wrote :ipvfour (singular!)
sled
By the way: the order the fields are sent to your controller doesn't matter the nesting is important, means the "ipvfours" has to be inside of the "machine" ;)
sled
if I do that I cannot see ip fields in my new machine page. I do not really understand why.
Goueg83460
Hi, did you put the @machine.ipvfours.build in your "new" action?
sled
@machine.ipvfours.build I set this but I have one errorundefined method `build' for nil:NilClass
Goueg83460
this means @machine.ipvfours does not exists! 1) make sure you have this in your machine model: has_many :ipvfours 2) make sure you have @machine = Machine.new in your new action before you do @machine.ipvfours.build
sled
yes that works thank you very much for your help. I think now I can understand better the process. Thanks again.
Goueg83460
A: 

I'm sorry I need again some helps. After have those two table I added a new one: Owner.

This table contains only some people name. And I configured it as following:

Owner models

class Owner < ActiveRecord::Base
    has_many :machines, :dependent => :destroy
    accepts_nested_attributes_for :machines

    # resturn value for table in index page.
   def to_s
     "  #{name}"
   end
end

machines models

 class Machine < ActiveRecord::Base
    has_many :ipvfours, :dependent => :destroy
    belongs_to :owners
    accepts_nested_attributes_for :ipvfours
    accepts_nested_attributes_for :owners
 end

first thing is that in my table I do now see any owner and if I try to create new machine I have following error:

ActiveRecord::AssociationTypeMismatch in MachinesController#create

Owner(#60450264) expected, got Array(#35557212)

def new
    @machine = Machine.new
    @machine.owners.build
    @machine.ipvfours.build
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @machine }
    end
 end

I don't understand as I think I correctly set has_one and belong_to

Thanks in advance

Goueg83460