Forum: Ruby on Rails save new model with child model

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Peter M. (Guest)
on 2006-04-26 10:01
(Received via mailing list)
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
Peter M. (Guest)
on 2006-04-26 22:45
(Received via mailing list)
On 4/25/06, Peter M. <removed_email_address@domain.invalid> 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
Jeremy M. (Guest)
on 2006-04-27 18:15
(Received via mailing list)
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
Peter M. (Guest)
on 2006-04-27 20:16
(Received via mailing list)
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.
Peter M. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
Hi,

Please tell me there is something simpler.

Peter
Daniel -. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
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?
Peter M. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
Hi Liquid,

On 4/30/06, Liquid <removed_email_address@domain.invalid> 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
Daniel -. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
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
Daniel -. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
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:
<code lang='ruby'>

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

</code>

Comment Model:
<code lang='ruby'>

class Comment < ActiveRecord::Base
  belongs_to :ticket
end

</code>

Ticket Controller:
<code lang='ruby'>

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

</code>

Ticket View - New
<code lang='ruby'>

<%= start_form_tag :action => :new %>
    Ticket Title: <%= text_field "ticket", "title" %>
    <br/>
    Comment: <%= text_field "comment", "description" %>
    <br/>
    <%= submit_tag %>
<%= end_form_tag %>

</code>
Peter M. (Guest)
on 2006-05-03 20:57
(Received via mailing list)
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
Daniel -. (Guest)
on 2006-05-03 20:58
(Received via mailing list)
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 topic is locked and can not be replied to.