Rating con act_as_rateable plugin

Desde luego una de las mayores ventajas de Rails es la existencia de los plugins y gemas que nos permiten no comernos la cabeza con cosas repetitivas, pesadas o simplemente no tener que reinventar la rueda.

En esta caso tenia que hacer un sistema para puntuar cosas con las típicas estrellítas que podemos ver en YouTube o en otras tantas webs de hoy en día. Finalmente lo conseguí, eso si gracias al plugin act_as_rateable, los gráficos de Komodomedia y la pequeña guía de Naffis.

La mayor diferencia entre la guía de Naffis y los pasos que yo pondré aquí es que aquí te enseñaré a sacarle toda la potencia pudiendo hacer el sistema polimórfico.

Advierto que a menos que estés interesado no sigas leyendo porque es un autentico ladrillo, eso si, el resultado es muy bonito :D

Lo primero es instalar el plugin act_as_rateable con:

  1. script/plugin install http://juixe.com/svn/acts_as_rateable

Hecho esto tendremos que crear una migración con los campos necesarios para nuestro sistema de rating, en un archivo como “db/migrate/xxx_create_ratings.rb” escribimos:

  1. class CreateRatings< ActiveRecord::Migration
  2.  
  3.   def self.up
  4.     create_table :ratings, :force => true do |t|
  5.       t.column :rating, :integer, :default => 0
  6.       t.column :created_at, :datetime, :null => false
  7.       t.column :rateable_type, :string, :limit => 15,
  8.       :default => "", :null => false
  9.       t.column :rateable_id, :integer, :default => 0, :null => false
  10.       t.column :user_id, :integer, :default => 0, :null => false
  11.     end
  12.  
  13.     add_index :ratings, ["user_id"], :name => "fk_ratings_user"
  14.   end
  15.  
  16.   def self.down
  17.     drop_table :ratings
  18.   end
  19.  
  20. end

Realizamos la migración:

  1. rake migrate

Creamos el controlador que se encargue nuestros ratings en “rating_controller.rb” por ejemplo:

  1. class RatingController < ApplicationController
  2.   def rate
  3.     rateable_type = params[:rateable_type]
  4.     @asset = eval(rateable_type).find(params[:id])
  5.     Rating.delete_all(["rateable_type = ? AND rateable_id = ? AND user_id = ?", rateable_type, @asset.id, current_user.id])
  6.     @asset.add_rating Rating.new(:rating => params[:rating], :user_id => current_user.id)
  7.   end
  8. end

Ya falta menos, ahora debemos generar las vistas de nuestro rating, creamos la carpeta “rating” en “views” y dentro de el creamos dos archivos:

_rating.html.erb

  1. .star-rating {
  2.   list-style: none;
  3.   margin: 0px;
  4.   padding: 0px;
  5.   width: 125px;
  6.   height: 25px;
  7.   position: relative;
  8.   background: url(/images/star.gif) top left repeat-x; }
  9.   .star-rating li {
  10.     padding: 0px;
  11.     margin: 0px;
  12.     float: left; }
  13.     .star-rating li a {
  14.       display: block;
  15.       width: 25px;
  16.       height: 25px;
  17.       text-decoration: none;
  18.       text-indent: -9000px;
  19.       z-index: 20;
  20.       position: absolute;
  21.       padding: 0px; }
  22.       .star-rating li a:hover {
  23.         background: url(/images/star.gif) left center;
  24.         z-index: 2;
  25.         left: 0px;
  26.         border: none; }
  27.     .star-rating li.current-rating {
  28.       background: url(/images/star.gif) left bottom;
  29.       position: absolute;
  30.       height: 25px;
  31.       display: block;
  32.       text-indent: -9000px;
  33.       z-index: 1; }
  34.   .star-rating a.one-star {
  35.     left: 0px; }
  36.     .star-rating a.one-star:hover {
  37.       width: 25px; }
  38.   .star-rating a.two-stars {
  39.     left: 25px; }
  40.     .star-rating a.two-stars:hover {
  41.       width: 50px; }
  42.   .star-rating a.three-stars {
  43.     left: 50px; }
  44.     .star-rating a.three-stars:hover {
  45.       width: 75px; }
  46.   .star-rating a.four-stars {
  47.     left: 75px; }
  48.     .star-rating a.four-stars:hover {
  49.       width: 100px; }
  50.   .star-rating a.five-stars {
  51.     left: 100px; }
  52.     .star-rating a.five-stars:hover {
  53.       width: 125px; }

rate.rjs

page.replace_html “star-ratings-block”, :partial => ‘rating/rating’, :locals => { :asset => @asset }

Y para terminar con las vistas nos faltan los estilos y las imágenes necesarias, que podremos sacar de Komodomedia, en este caso tendremos que añadir a nuestro archivos .css las siguientes lineas de código:

  1. class Image < ActiveRecord::Base
  2.   …
  3.   acts_as_rateable
  4.   …
  5. end

Y para que valla como la seda tendréis que guardar en vuestra carpeta “images” en “public” la imagen star.gif

Ya con esto lo tenemos todo casi listo, ahora solo nos falta decidir que queremos que sea “rateable”, por ejemplo si tememos el controlador “image.rb” haremos:

  1. <%= render :partial => "rating/rating", :locals => { :asset => @image } %>

En este caso vemos que el modelo controla unas imágenes, lo más habitual para esto sería poder “ratearlas” en el show. Pues en el show.html.erb pegamos:

  1. @image = Image.find :first #por ejemplo

@image sería el objeto generado en tu controlador por:

  1.  

Estos dos últimos pasos son los únicos que tendremos que repetir para añadirlos a otros modelos como Videos, Posts, etc.

Seguro que tu puedes mejorarlo, refactorizarlo, incluso tener tantas estrellas máximas como puedas.

¿Encontráis fallos?

Sin comentarios ↓

Nadie ha dejado ningún comentario, tu puedes ser el primero.

Leave a Comment