Save new model with child model

Hi,

I am having a problem saving a new model that has an associated child
model. If a new ticket is being created and will have one comment to
go with it then I tried this in my action

  @ticket = Ticket.new(params[:ticket])
  @comment = Comment.new(params[:comment])
  @ticket.comments << @comment
  if @ticket.save
      @notice = "Ticket added. Thanks for contributing!"
      @ticket = Ticket.new
      @comment = Comment.new
  else
    @notice = "Sorry, unable to add ticket."
  end

The save always fails because the comment does not have a ticket_id
specified. How can I specify the ticket_id for the comment if the
ticket id doesn’t even exist before I call save. I thought Rails would
take care of this for me when I use the << or push(). (Rails 1.0)

Any ideas what to do?

Thanks,
Peter

On 4/25/06, Peter M. [email protected] wrote:

Hi,

I am having a problem saving a new model that has an associated child
model. If a new ticket is being created and will have one comment to
go with it then I tried this in my action

[snip]

I am current going to all this effort which just seems wrong.

  @ticket = Ticket.new(params[:ticket])
  @comment = Comment.new(params[:comment])

  if @ticket.save
    @comment.ticket_id = @ticket.id
    @ticket.comments << @comment
    if @comment.save
      @notice = "Ticket added"
    else
      @ticket.destroy
      @notice = "Sorry, unable to add ticket."
    end
  else
    @notice = "Sorry, unable to add ticket."
  end

There must be a simpler way. Any ideas?

Thanks,
Peter

Hi Jeremy,

Thanks for the code. Unfortunately it didn’t work:S The save still
results in an error because the ticket_id is not set for the comment.
What to do?

Thanks
Peter

On 27 Apr 2006 14:14:52 -0000, Jeremy M.

You almost have it. Try:

def new
@ticket = Ticket.new
@comment = Comment.new
render :action => ‘new’
end

def create
@ticket = Ticket.new(params[:ticket])
@comment = Comment.new(params[:comment])
@comment.ticket = @ticket

if @comment.save
  flash[:notice] = "Ticket added. Thanks for contributing!"
  redirect_to :action => 'new'
else
  flash[:notice] = "Sorry, unable to add ticket."
  render :action => 'new'
end

end

Hi,

Please tell me there is something simpler.

Peter

Is the comment attached with a through relationship, or a straight
has_many?

the << does not work with through relations.

Otherwise with a normal has_many,

@ticket = Ticket.new(params[:ticket])
@ticket.comments << Comment.new(params[:comment])
@ticket.save!

should set the foreign keys automatically in the Comment object as I
understand it.

Could you post the relevant lines of your Ticket model?

I’m at work at the moment, I’ll look at it when I get home…

Just one more thought though.

Have you tried

@ticket.comments.create( Comment.new(params[:comment])

This may work… Failing this I will try it when I get home

Hi Liquid,

On 4/30/06, Liquid [email protected] wrote:

Is the comment attached with a through relationship, or a straight has_many?

the has_many is just a regular relationship

Could you post the relevant lines of your Ticket model?
class Ticket < ActiveRecord::Base
has_many :comments, :dependent=>:delete_all
end

Any ideas why it might not work? I doubt this is a bug in Rails but I
don’t seem to be doing anything obviously wrong.

Thanks,
Peter

Hi Liquid,

Thank you for the investigation. Wow!

In my table definitions I have something like

id INT NOT NULL

I will try changing this and let you know what happens. It seems like
this is probably the problem.

I really appreciate your help.

Peter

Hi Peter,

I had tried some test code without any problems. I have included the
code
below for the example that I used.

Can you post your table definitions?

Table Defs:
tickets
id INT
title STRING

comments
id INT
description STRING
ticket_id INT

Ticket Model:

class Ticket < ActiveRecord::Base
has_many :comments, :dependent => :delete_all
end

Comment Model:

class Comment < ActiveRecord::Base
belongs_to :ticket
end

Ticket Controller:

class TicketController < ApplicationController

def list
@tickets = Ticket.find(:all)
end

def new
if request.post?
@ticket = Ticket.new(params[:ticket])
@ticket.comments << Comment.new(params[:comment])
if @ticket.save
flash[:notice] = “Saved”
redirect_to :action => :list
else
flash[:notice] = “Not Saved”
end
else
@ticket = Ticket.new
end
end

end

Ticket View - New

<%= start_form_tag :action => :new %>
Ticket Title: <%= text_field “ticket”, “title” %>


Comment: <%= text_field “comment”, “description” %>


<%= submit_tag %>
<%= end_form_tag %>

I don’t think that will help you.

The table defs that I used I did not completely specify in the post.

The ID column is NOT NULL that I used in both tables. All I included in
the
post was the column name and type. Sorri for the inconvienience.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs