Añadiendo Likes a nuestra aplicación
Seguramente ya te diste cuenta de que Ruby nos hace la vida mucho más sencilla gracias a las gemas, hoy usaremos acts as votable para añadir likes a nuestra aplicación.
Añadiendo la gema
Como es costumbre, comenzaremos con añadir la gema a nuestro archivo Gemfile
, añadela debajo de Cancan, tal que así:
gem 'cancancan'
gem 'acts_as_votable', '~> 0.10.0'
Instalala con $ bundle
, luego genera la migración requerida por la gema con $ rails g acts_as_votable:migration
y luego migra $ rails db:migrate
.
Configurando los Likes
Ahora, debemos hacerle saber a nuestra gema cuales modelos pueden recibir likes, para esto, abrimos el modelo fact.rb
y añadimos acts_as_votable
, de tal manera que queda así:
class Fact < ApplicationRecord
resourcify
acts_as_votable # NUEVA LÍNEA
has_attached_file :image, :styles => { :large => "1024x768", :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/default_image.png"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
validates :image, presence: true
belongs_to :user
has_many :comments, dependent: :destroy
end
Ya le hicimos saber a nuestra gema que los Facts pueden tener likes, ahora tenemos que hacerle saber quien puede votar, para ello, abre el modelo user.rb
y añade acts_as_voter
, quedaría así:
class User < ApplicationRecord
acts_as_voter # NUEVA LÍNEA
rolify
# Relationships
has_many :facts
# Devise custom fields
validates :name, presence: true, uniqueness: true
# Paperclip validations
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/default_avatar.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
validates_with AttachmentSizeValidator, attributes: :avatar, less_than: 1.megabytes
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Genial, nuestros modelos están listos, falta editar los permisos, de tal manera que un usuario este autorizado a dar likes, abre el archivo ability.rb
:
def initialize(user)
if user.has_role? :admin
can :manage, :all
else
can :read, :all
can :create, :all
can :upvote, Fact # NUEVA LÍNEA
end
can :update, Fact do |fact|
fact.user == user
end
can :destroy, Fact do |fact|
fact.user == user
end
end
Editemos nuestro controlador de tal manera que podamos dar likes, abre el archivo facts_controller.rb
, primero edita before_action :find_fact, only: [:show, :edit, :update, :destroy]
y añade :upvote
, quedaría así: before_action :find_fact, only: [:show, :edit, :update, :destroy, :upvote]
. Puedes haber notado que aún no hemos creado este método, debajo de:
def destroy
@fact.destroy
redirect_to facts_path, :notice => "Fact deleted successfully!"
end
Añade:
def upvote
@fact.upvote_by current_user
redirect_to :back
end
Ahora, tenemos que editar nuestras rutas, para poder hacer uso de este método desde nuestras vistas:
Rails.application.routes.draw do
devise_for :users
root "facts#index"
# DESDE AQUÍ CAMBIAMOS:
resources :facts do
member do
put "like", to: "facts#upvote"
end
end
end
Hemos terminado, solo falta añadir un botón que sirva para dar likes y mostrar la cuenta, en tu vista facts/show.html.erb
justo debajo de <% if current_user %>
añade:
<%= link_to like_fact_path(@fact), method: :put do %>
<div class="ui labeled button" tabindex="0">
<div class="ui blue button">
<i class="heart icon"></i> Like
</div>
<div class="ui basic blue left pointing label">
<%= @fact.get_upvotes.size %>
</div>
</div>
<% end %>
La mayoría son solo estilos, debes prestar atención a link_to like_fact_path(@fact), method: :put do
, donde le decimos que deseamos añadir un nuevo like al Fact actual usando el método put
(“actualizar”), además de <%= @fact.get_upvotes.size %>
donde contamos cuantos likes tiene nuestro Fact. Puedes ver los cambios realizados en el repositorío si te has confundido.
Eso es todo por esta serie, espero que hayan tenido la oportunidad de aprender algo nuevo y nos volveremos a ver en la red.