Sep 27, 2011

Enabling Comments on New Models in LovdByLess

Today a project I've been working on called for enabling comments on a new model that I'd introduced into a lovdbyless application. Took me a couple hours to figure it all out, so I thought I'd write down the steps. Hopefully I won't miss any
  1. Link the new model with the existing comments model. This is easy to do, just add the association with :as => :commentable line to the new model. My final model looked like this:
      
    class Rating < ActiveRecord::Base
      has_many :comments, :as => :commentable, :order => "created_at asc"
      belongs_to :profile
      belongs_to :title
      validates_presence_of :rating, :message => "You didn't supply a rating"
    
      validates_uniqueness_of :title_id, :scope => :profile_id, :message => "You've already told us about that title"
    end
    
  2. Create a route for the comments that belong to the new model. I added this to my routes.rb:
      
      map.resources :ratings do |rating|
        rating.resources :comments
      end
    
  3. I had an existing view/partial. I had to add this code to it to make a link to the existing Thickbox comment form. It's lifted straight from the _blog.html.erb and adapted for use with my model
  4. <%= "Comments (#{rating.comments.size})" %> | <%= inline_tb_link('Add a Comment', "#{dom_id(rating)}_new_comment", :title => "Leaving A Comment") if @p %>
    
  5. Same partial. Here too, code is borrowed from the _blog.html.erb partial to get things moving along. This code provides the summary for the comments related to the model element. It also provides the hidden comment form div.
    <% rating.comments.each do |c| %> <%= render :partial => 'comments/comment', :locals => { :comment => c } %> <% end %>
  6. The special sauce is the last step that I couldn't troubleshoot easily. If you get this far and try to execute, you'll get HTTP status 500 errors from Mongrel when you try to submit the ThickBox form. It's all done in AJAX, so it's not too easy to diagnose. I found the missing step was to add a line or two in comments_controller.rb for my new model The first bit of the protected section had to change. Ultimately, this sets the @parent which is needed in the create method
        def parent; @rating || @blog || @profile || nil; end
        
        def setup
          @profile = Profile[params[:profile_id]] if params[:profile_id]
          @user = @profile.user if @profile
          @blog = Blog.find(params[:blog_id]) unless params[:blog_id].blank?
          @rating = Rating.find(params[:rating_id]) unless params[:rating_id].blank?
          @parent = parent
        end
    
I've modified the css quite a bit, but this is the result I got: