ruby on rails - Table column that automatically calculates average rating -


i'm following tutorial , have models user, hotel , rating. users can create hotels, , users can rate them. users rating value recorded table rating user_id , hotel_id. when render partial <%= render "hotels/hotels_list", :@hotels => hotel.all %> shows list of hotels average rating calculates in model hotel model hotel.rb :

class hotel < activerecord::base   attr_accessible :user_id   belongs_to :user   has_many :ratings   has_many :raters, :through => :ratings, :source => :users    def average_rating     @value = 0     self.ratings.each |rating|       @value = @value + rating.value     end     @total = self.ratings.size     '%.2f' % (@value.to_f / @total.to_f)   end end 

model user.rb :

class user < activerecord::base   has_many :hotels   has_many :ratings   has_many :rated_hotels, :through => :ratings, :source => :hotels end 

model rating.rb :

class rating < activerecord::base   attr_accessible :value   belongs_to :user   belongs_to :hotel end 

i need sort list of hotels average rating, maybe need add column average_rating @ once calculate average value average_rating method in hotel model, can access it. how can solve issue? ratingscontroller.rb

class ratingscontroller < applicationcontroller        before_filter :authenticate_user!       def create         @hotel = hotel.find_by_id(params[:hotel_id])         @rating = rating.new(params[:rating])         @rating.hotel_id = @hotel.id         @rating.user_id = current_user.id         if @rating.save           respond_to |format|             format.html { redirect_to hotel_path(@hotel), :notice => "your rating has been saved" }             format.js           end         end       end        def update         @hotel = hotel.find_by_id(params[:hotel_id])         @rating = current_user.ratings.find_by_hotel_id(@hotel.id)         if @rating.update_attributes(params[:rating])           respond_to |format|             format.html { redirect_to hotel_path(@hotel), :notice => "your rating has been updated" }             format.js           end         end       end      end 

very simple. first, add average_rating column hotel model migration. then, add callback rating model updates value in hotel model. basically, every time rating created, destroyed, or updated, need update average rating. this:

class hotel < activerecord::base   [ code snipped ]    def update_average_rating     @value = 0     self.ratings.each |rating|       @value = @value + rating.value     end     @total = self.ratings.size       update_attributes(average_rating: @value.to_f / @total.to_f)   end end  class rating   belongs_to :hotel   after_create :update_hotel_rating    def update_hotel_rating     hotel.update_average_rating   end end 

now can sort rating. i'm leaving details out think can general idea here.


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

html - Repeat image to extend header to fill screen -

javascript - Backbone.js getting target attribute -