Re: Creating Two Models in One Form

Thank you for answering Ryan, your genuine interest in beginners questions keeps us motivated to learn; that is really very nice of you.
I have looked over your tutorials many times, now I am just uncertain as to what to do.


I have one model that collects demographics for a person.
My second model collects a set of test data for that person. It is always the same test, but it can be done more than one time. I want to add one test at a time.


person has_many :tests and test belongs_to :person.


So far, I am able to create a person and the first test and also update, destroy etc..

I am looking for ways to add a second, third test etc to that same person.


While looking at 'project with multiple tasks' I got lost early in the 'def new' how that will apply to my problem.



Thus: can I use the 'project/multiple tasks' tutorial for my problem ? I just want to add one test at a time.




Thanks again for your interest, it's fabulous.

Re: Creating Two Models in One Form

Shouldn't this add a new test for a person ?

In person/list.rhtml:

<%= link_to 'Add test', :action => 'add_test', :id => person %>

in PersonController

def add_test
person = Person.find(params[:id])
@test = Test.new(:person => person)
render :template => 'test/edit'
end

Re: Creating Two Models in One Form

Okay, so you just want to add tests individually? In that case I recommend creating a "TestsController" with "new" and "create" actions. You can generate this with scaffolding if you want.

Then you just have to link the "add test" method to that "new" action and pass the person_id to it.

If you are still having problems I recommend creating a new thread for this.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Two Models in One Form

Hi Ryanb,

your tutorial cought my eye becouse I would need to do the same thing. I just started learning ruby on rails, and I have tryed the method that you discribed. But it doesn't seem to work.

I'm just building a simple application to hold contact persons. I created everything using the ruby generation scripts. Even the form (used the scaffold to generate it). But now comes the tricky part for me. Every contact can have 0 to many notes. The thing is that I would like that the notes can be written in the edit/new form of a contact person.

I allready discribed most of it with some code samples how I managed so far in this post.

So I hoped that you could give me some pointers how to save new/edited notes.

Thank you in advance

Re: Creating Two Models in One Form

It appears the problem you mentioned in the other thread is related to editing. This tutorial is only for creating models, not for editing them. See this tutorial on how to do that.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Two Models in One Form

Great tutorial, but how can I make a form that allows you to input multiple tasks in one go?

Re: Creating Two Models in One Form

See this tutorial on how to do that.

Railscasts - Free Ruby on Rails Screencasts

Re: Creating Two Models in One Form

Hi,

I have to models, 'label' and 'image':

label has_one :image
image belongs_to :label

I am trying to generate a single form using the info in this tutorial. So that a user can add a new label and upload an image at the same time. I have also installed the attachment_fu and mini-magick plugins...

Below are my files:

The images migration/table;

class CreateImages < ActiveRecord::Migration
  def self.up
    create_table :images do |t|
      t.column :parent_id,  :integer
      t.column :content_type, :string
      t.column :filename, :string   
      t.column :thumbnail, :string
      t.column :size, :integer
      t.column :width, :integer
      t.column :height, :integer
      t.column :label_id, :integer
    end
  end

  def self.down
    drop_table :images
  end
end


new.rhtml;

<h2>Add new Label</h2>

<%= error_messages_for :label, :image %>

<% form_for(:label, @label, :url => { :action => 'create'}, :html => { :multipart => true }) do |f| %> 
  <p>
      <label for="label_name">Name:</label><br/ >
      <%= f.text_field :name %>
  </p>
  <p>
      <label for="label_country">Country:</label><br/ >
      <%= f.text_field :country %>
  </p>
  <p>
    <label for="label_website">Website:</label><br/ >
      <%= f.text_field :website %>
  </p>
  <p>
      <label for="label_email">Email:</label><br/ >
      <%= f.text_field :email %>
  </p>
   <% fields_for(:image, @label.image) do |i| %>
  <p>
    <label for="label_image">Image:</label><br />
    <%= i.file_field :uploaded_data %>
  </p>
  <% end %>
    <%= submit_tag 'Create' %>
<% end %>


label_controller.rb;

def new
  @label = Label.new
  @image = Image.new
end

def create
@label = Label.new(params[:label])
@image = @label.build_image(params[:image])
  if @label.save
  redirect_to :action => 'list'
  else
  render :action => 'new'
  end
end


image.rb;

class Image < ActiveRecord::Base
belongs_to :label

has_attachment :content_type => :image,
                 :storage => :file_system,
                 :path_prefix => 'public/upload',
                 :max_size => 500.kilobytes,
                 :resize_to => '320x200>',
                 :thumbnails => { :thumb => '100x100>' }

validates_as_attachment

end


When i submit the form, the new label is added, but there us no image uploaded, and the image tables is empty...

Any help appreciated...

Thanks,

Pj,

Last edited by pjay79 (2007-11-11 23:24:05)

Re: Creating Two Models in One Form

I have tried the tutorial but I have this haunting problem :I have two model

class User < ActiveRecord::Base
  has_many :user_phones
  has_many :users, :through =>:user_phones
end

class UserPhone < ActiveRecord::Base
    belongs_to :phone
    belongs_to :user
end

class Phone < ActiveRecord::Base
    has_many :user_phones
       has_many :users, :through =>:user_phones
end


The code snippet for my controller :

def register
   
   if request.post?
      @user = User.new(params[:user])
      @phones = Phone.new(params[:phone])

    if @user.valid? &&  @phones.valid?
        
        @user.opening_date = Time.now
        user.last_update_date = Time.now
        @user.last_access_date = Time.now
        @user.expiration_date = 60.days.from_now
        @user.UUID = UUID.timestamp_create().to_s
        @user.phones << @phones
        if @user.save
        flash[:notice] = 'You have Successfully Registered'
        end
        #  redirect_to :action => 'register'
    end
  end


The error I get after registration :

"Cannot associate new records through 'User#user_phones' on '#'. Both records must have an id in order to create the has_many :through record associating them."

Can someone rescue me in this one ;

Thanx

Re: Creating Two Models in One Form

Actually I managed to figure it out , I was very close but not quite :

   @user.expiration_date = 60.days.from_now
    @user.UUID = UUID.timestamp_create().to_s
    @phones.save  # the line I need to insert to make the whole thing work
    @user.phones << @phones
    if @user.save

Cheers

Re: Creating Two Models in One Form

ryanb, can you update this with using form_for and fields_for? Rails 2.0 smile

Re: Creating Two Models in One Form

When the Project validation returns an error it's also returning "Tasks is invalid" along with any errors associated with tasks. How do you prevent this?

Re: Creating Two Models in One Form

Anyway..what if project has_one :task.
@task = @project.tasks.build(params[:task]) <-- is this working?What is the solution?

Re: Creating Two Models in One Form

jstad wrote:

ryanb, can you update this with using form_for and fields_for? Rails 2.0 smile

jstad, I just learned Rails last couple of days, I'm not sure if this is the correct way to do it but I'm sure it works.

Refer to Ryan's post, everything else remain the same, except for new.html.erb

# in the projects/new.html.erb
<h1>New Project</h1>

<%= error_messages_for :project, :task %>

<% form_for(@project) do |f| %>
<p>
  Project Name:
  <%= f.text_field :name %>
</p>
<% fields_for(@task) do |i| %>
<p>
  First Task:
  <%= i.text_field :name %>
</p>
<% end %>
<p>
  <%= f.submit 'Create' %>
</p>
<% end %>

Re: Creating Two Models in One Form

Thanks to this tutorial I finally figured this out.  However, I have a question.  How would I check to see if a task already exists to avoid duplicates?  I would allow two projects to have the same task, but I would not want them duplicated in the tasks table

Last edited by tokyo2002 (2008-05-02 08:17:42)

76

Re: Creating Two Models in One Form

In task.rb:

validates_uniqueness_of :title # or whatever your column's name is

Re: Creating Two Models in One Form

I need some help here guys

It's really frustating when you read somebody posting exactly what you are doing yet for you it does not work.

Here is my problem, i have a relation 1:1 user - profile (1 user has 1 profile), profile is just for personal information (name, last name...) and user for his account information (password, login...)

I have a user/new view, wich is a form to add a new user
It adds correctly to the user table, BUT the profile table remains empty when it should add a row with the user_id
it's something so basic yet so complicated on ruby on rails?

User Model:

  has_one :profile, :dependent => :destroy

Profile Model:
  belongs_to :user, :foreign_key => "user_id"

Yes, the profile table has the user_id column (double checked!)

Now the important, the user controller:

def new
    @user = User.new
    @profile = Profile.new   
end
def create
    cookies.delete :auth_token
    @user = User.new(params[:user])
    @profile = @user.build_profile(params[:profile])   
    @user.save!
    render :action => 'verify' #just displays a welcome msg
  rescue ActiveRecord::RecordInvalid
    render :action => 'new'
  end

No big deal on my user/new view, just the relevant part:
<% form_tag('/users/create', :method => :post, :multipart => true) do %>

The view has all the fields and they are working as it is adding the user to the user table (with all the info), but the profile table has no rows
When it should add a row with the corresponding user_id


Rigth now it's really temptating to give up on this and merge the table profile with user and the problem will be gone
it's just, having 37 columns in one table doesn't seem rigth..

and how come it works for you guys?

Re: Creating Two Models in One Form

arzumy,

I tried using your suggestion and it did not work for me - I also would like to be able to use this technique with Rails 2.0. Is there any chance you left somsething out?

Re: Creating Two Models in One Form

I started playing around with things, and I have gotten closer to getting this to work on 2.0. In my new.html.erb file I used

 ...
  <% for task in @project.tasks %>
  <% fields_for(task) do |i| %>
      <p>
      Task: <%= i.text_field :name %>
      </p>
  <% end %>
  <% end %>
...

and tracked down the params hash to see what it was spitting back when I made a project "foo" with tasks "bar", "and not" and "rue barb" (mmm, ruebarb) and found that the Parameters hash came out as
{"commit"=>"Create", "project"=>{"name"=>"foo"}, "authenticity_token"=>"0037c530b27131910d7e44219b87b2ee8ffc17f7", "action"=>"create", "task"=>{"name"=>"bar"}, "controller"=>"projects"}

Once I did this (which I should've done much sooner - been busy) I noticed that the "task" key maps to only a single hash, not a set of several as it should. Ignoring this for the moment, I decided to see if I could get at least that value to save properly, so I used
...
  def create
    @project = Project.new (params[:project])
    @tasks = @project.tasks.build params[:task]
...

in my projects_controller.rb file. Sure enough, when I did this I was able to get the value to actually save for the first of the three fields_for entry fields, but the two (as expected) did not save.

Can anyone help me get all of the task params out of the fields_for?

Thanks

Re: Creating Two Models in One Form

Bizzare - I tried Ryanb's code again and this time it worked for me. I must have typed something in wrong while following his screencast. Looks like you don't have todo anything different in 2.0.