Noz
Noz

Reputation: 6346

Rails How To Manually Create Child Object Without Form

I was wondering what the best implementation would be to programatically generate a single child object for a parent(s) without the use of a form.

In my case I have an existing forum system that I would like to tie into my Upload system via comments. I would like to manually create a child Forum object to discuss said upload in the same create action that the Upload is created. The two models have a relationship as so:

Child forum:

class Forum < ActiveRecord::Base
   ...
   belongs_to :upload
end

Parent upload:

class Upload < ActiveRecord::Base
   ...
   has_one :forum
end

I was thinking of something along the lines of:

class UploadsController < ApplicationController
  ...
  def create
    #Create the upload and a new forum + initial post to discuss the upload
    @upload = Upload.new(params[:upload])
    @forum = Forum.new(:upload_id => @upload.id, :title => @upload.name...)
    @first_post = Post.new(:forum_id => @forum.id....)    
    if @upload.save && @topic.save && @first_post.save
      redirect_to :action => "show", :id => @upload.id
    else
      redirect_to :action => "new"
    end 
  end

end

Which is fairly close to what I wanted to do but the parent ids aren't generated until the parent objects are saved. I could probably do something like:

@upload.save 
@forum = Forum.new(:upload_id => @upload.id...
@forum.save....

But I thought it might be cleaner to only persist the objects if they all validated. I'm not sure, does anybody else know of a better implementation?

Upvotes: 1

Views: 1413

Answers (1)

scarver2
scarver2

Reputation: 7995

I would recommend moving the forum creation from the controller to the model. The forum will only be created on the successful creation of the Upload.

class Upload < ActiveRecord::Base
  ...
  has_one :forum
  after_create :create_forum
  ...
  def create_forum
    Forum.create(:upload_id => self.id, :title => self.name...)
  end
end


class Forum < ActiveRecord::Base
  ...
  has_many :posts
  after_create :create_first_post
  ...
  def create_first_post
    Post.new(:forum_id => self.id)
    # or self.posts << Post.new()
  end
end

Upvotes: 3

Related Questions