3

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?

4 Answers 4

5

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
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.