views:

309

answers:

4

This is a tough one I think. I have a comments controller, that I'd like to use for all of my other controllers: such as books, titles, etc.

The problem is, the create action in comments is:

  def create
  @book = Book.find(params[:book_id])
  @comment = @book.comments.create!(params[:comment])
  respond_to do |format|
    format.html {redirect_to @book}
    format.js
  end

end

so how can I use the action & comments controller for titles, if its clearly using books attributes?

A: 

That's something I've mulled over too. You'd have to make the create method independent of the parent, first of all.

Then you'd have a couple options:

  1. Have a belonsg_to for every thing the comment could possibly be attached to, and selectively fill one of them out.
  2. Have the books/titles/etc belongs_to the comment

I'm fairly new to Rails myself, so I don't know of that's the "correct way" of doing things, maybe someone else has a better solution.

Karl
A: 

Well, you can't do this generally without being specific about attribute for each of the controllers.

If you wanted to to create a general comments model for a bunch of models in your application, you'd need to pass on the model type that you're commenting to (but not the model itself), and then create a switch that would provide different behaviour based on what you pass.

def create
  if params[:type]="book"
    @book = Book.find(params[:book_id])
    @comment = @book.comments.create!(params[:comment])
    respond_to do |format|
      format.html {redirect_to @book}
      format.js
  elsif params[:type]="title"
    @title = Title.find(params[:title_id])
    @comment = @title.comments.create!(params[:comment])
    respond_to do |format|
      format.html {redirect_to @title}
      format.js
  end
end
Richard Seviora
A: 

I think the resource controller is probably what you're looking for. Here's another link on the resource controller.

Andy Gaskell
+2  A: 

I'm assuming you have a polymorphic association setup on comment so it can belong to many different types of models? Take a look at this Railscasts episode which shows you how to set that up along with the controller action. Here's the key bit of code.

# comments_controller
def create
  @commentable = find_commentable
  @comment = @commentable.comments.build(params[:comment])
  if @comment.save
    flash[:notice] = "Successfully created comment."
    redirect_to :id => nil
  else
    render :action => 'new'
  end
end

private

def find_commentable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end
  nil
end

# routes.rb
map.resources :books, :has_many => :comments
map.resources :titles, :has_many => :comments
map.resources :articles, :has_many => :comments
ryanb