owned this note
owned this note
Published
Linked with GitHub
<style>
.reveal h2 {
text-align:center;
font-size: 50px;
color: #fd3;
margin-bottom: 8px;
}
p.part {
text-align: left;
font-size: 20px;
}
.reveal .code-wrapper {
border-radius: 4px;
width: 100%;
}
.code-wrapper > *::-moz-selection {
color: #222;
background: #fd3;
}
.path {
color: #fd3;
}
.comando {
background: #333;
border-radius: 4px;
padding: 0 6px 3px 6px;
}
.comando::before {
content: "> "
}
.language-bash::before {
content: "$ "
}
.language-dos::before {
content: "> "
}
.irb {
background: #282828;
border-radius: 4px;
padding: 0 6px 3px 6px;
}
.irb::before {
content: "irb(main):001:0> ";
color: #2f3;
}
.code-wrapper > *::selection,
.hljs-tag::selection,
.hljs-tag > *::selection,
.hljs-symbol::selection,
.language-ruby > *::selection,
.hljs > *::selection,
.hljs-ln-code::selection,
.hljs-ln-code > *::selection,
.hljs-ln-code > * > *::selection,
.hljs-ln-code > * > * > *::selection,
.hljs-class > *::selection,
.comando::selection,
.comando > *::selection,
.irb > *::selection{
color: #222;
background: #fd3;
}
.reveal .code-wrapper code {
white-space: pre;
}
pre.flow-chart, pre.sequence-diagram, pre.graphviz, pre.mermaid, pre.abc, pre.vega {
background: #222;
border-bottom: 1px solid #ccc;
width: 100%;
}
img {
width: 100%;
margin: 0 !important;
}
h4 {
text-align: left;
}
.reveal ul{
text-align: left !important;
font-size: 23px;
}
</style>
## REQ1: Set-up inicial
Creación del proyecto:
```bash
rails new crazy4cats -d postgresql
```
Modificar datos de conexión a través de credenciales:
**BASH** <i class="fa fa-terminal"></i>
```bash
EDITOR="code --wait" rails credentials:edit
```
**CMD** <i class="fa fa-terminal"></i>
```bat
set EDITOR=code --wait && rails credentials:edit
```
<div style="display: flex; font-size: 32px; gap: 12px">
<div style="">
Modifica los valores de conexión
```yml=
db:
username: user_db
password: password_db
```
</div>
<div style="">
En el archivo <span class="path">config/database.yml</span> carga los valores
```yml=23
username: <%= Rails.application.credentials.db[:username] %>
password: <%= Rails.application.credentials.db[:password] %>
```
</div>
</div>
Ahora corremos el comando para crear la base de datos: <span class="comando">rails db:create</span>
---
## Contexto principal
*Marcelo busca poder publicar sus aventuras con sus gatos y espera que todos sus usuarios puedan hacer lo mismo, podrán dar Me gusta o no me gusta a cada publicación que se suba a la página web*
*Los comentarios pueden ser anónimos como hechos por un usuario. Por último, solicita poder entrar el de cualquier ubicación*
```mermaid
erDiagram
USERS ||--|{ REACTIONS :has
PUBLICATION ||--|{ REACTIONS :has
```
<div style="display: flex; justify-content: space-between">
<div style="">
1\. añadir Devise al Gemfile:
```ruby=74
gem 'devise'
```
</div>
<div style="">
2\. actualizar la instalación:
```bash
bundle
```
</div>
<div style="">
3\. instalar el generador de Devise:
```bash
rails generate devise:install
```
</div>
</div>
---
Crear el modelo de usuario con el generador de Devise:
```bash
rails generate devise User name role:integer
```
En el archivo generado en <span class="path">db/migrate/2.....28_devise_create_users.rb</span> definimos lo siguiente:
```ruby=36
t.integer :role, default: 0
```
Generar un scaffold para el modelo Publicación:
```bash
rails g scaffold Publication banner title content:text
```
Generar una migración para añadir la relación de usuarios a las publicaciones:
```bash
rails g migration AddUsersToPublications user:references
```
Generar un modelo para Comentario:
```bash
rails g model Comment user:references publication:references body:text
```
Generar el modelo para Reacción:
```bash
rails g model Reaction kind publication:references user:references
```
Y corremos la migración: <span class="comando">rails db:migrate</span>
---
Añadimos la asociación en <span class="path">app/models/user.rb</span> y añadimos los roles usando el método [enum](https://api.rubyonrails.org/v7.0.5/classes/ActiveRecord/Enum.html) :
```ruby=2
has_many :comments, dependent: :destroy
has_many :reactions
has_many :publications, through: :reactions
enum :role, [:normal_user, :admin]
```
Añadimos la asociación en <span class="path">app/models/publication.rb</span> y agregando lo siguiente:
```ruby=2
belongs_to :user
has_many :comments, dependent: :destroy
has_many :reactions
has_many :users, through: :reactions
```
Validamos la cantidad de reacciones en el modelo <span class="path">app/models/reaction.rb</span> y un método para mostrar los tipo de reacciones:
```ruby=4
belongs_to :publication, optional: true
belongs_to :user
validates :kind, acceptance: { accept: %w[like dislike] }
def self.kinds
%w[like dislike]
end
```
---
Generamos el controlador para las reacciones:
```bash
rails g controller reactions
```
Agregamos el método para reaccionar y limitar la acción en <span class="path">app/controllers/reactions_controller.tb</span>:
```ruby=2
before_action :authenticate_user!
def user_reaction
@user = current_user
@publication = Publication.find(params[:publication_id])
reaction = Reaction.find_by(user_id: @user.id, publication_id: @publication.id)
if reaction
return flash.now[:alert] = 'Ya haz reaccionado a esta publicación'
else
@new_reaction = Reaction.new(user_id: @user.id, publication_id: @publication.id)
respond_to do |format|
if @new_reaction.save!
format.html { redirect_to publication_path(@publication), notice: "Haz reaccionado con un #{@new_reaction.kind}"}
else
format.html { redirect_to publication_path(@publication), status: :unprocessable_entity }
end
end
end
end
```
Configuramos la ruta en <span class="path">config/routes.rb</span>:
```ruby=
post '/reactions', to: 'reactions#user_reaction', as: 'user_reaction'
```
---
Agregamos un partial en <span class="path">app/views/reactions/_option.html</span> y añadimos lo siguiente:
```erb
<div class="container">
<ul>
<% Reaction.kinds.each do |kind| %>
<li>
<%= button_to "#{kind}", user_reaction_path(publication_id: @publication.id, kind: kind), method: :post %>
</li>
<% end %>
</ul>
</div>
```
Agregamos un partial en <span class="path">app/views/reactions/_counter.html</span> y añadimos lo siguiente:
```erb
<div class="container">
<ul>
<% Reaction.kinds.each do |kind| %>
<li>
<%= @publication.reactions.where(kind: kind).count %> - <%= kind %>
</li>
<% end %>
</ul>
</div>
```
---
Agregamos el partial en <span class="path">app/views/publications.html.erb</span>: