Creando una sencilla Plataforma de Blogs - Las Publicaciones

Por:, en:

ES:This tutorial assumes you have already completed:

  1. Install Ruby on Rails
  2. Create Ruby on Rails application
  3. Create Static Pages - without this deploy will not work
  4. Install Git
  5. Create Remote Git Repository - optional but recommended
  6. Deploy application to Heroku
  7. Manage users with Devise
  8. How to add Twitter Bootstrap to Ruby on Rails application - Advised
  9. Creating Simple Blogging Platform - Creating Model
  10. Creating Simple Blogging Platform - Routes
  11. Creating Simple Blogging Platform - Displaying Posts

Ahora que tenemos una manera de mostrar las publicaciones, podemos seguir adelante y comenzar a crearlas usando formularios.

Paso 1: Crea la acción "New"

Empezaremos añadiendo una "nueva" acción a nuestro controlador:

/app/controllers/posts_controller.rb


class PostsController < ApplicationController

    def index
        @posts = Post.all
    end

    def show
        @post = Post.find(params[:id])
    end

    def new
    end

end

Paso 1.2: "instancia" Post en controlador

Esta vez dentro de la acción "instanciaremos" la nueva publicación y  la guardaremos como variable. Al igual que lo hicimos antes en la línea de comandos:

/app/controllers/posts_controller.rb

def new
    @post = Post.new
end

Paso 1.3: Crea un nuevo archivo de HTML

Ahora podemos proceder con la creación de una plantilla para nuevas publicaciones. Dentro de  /app/views/posts/ crea un nuevo archivo llamado "new.html.erb" y en el, agrega el siguiente código:

/app/views/posts/new.html.erb


    <%= form_for @post do |f| %>
        <div class="form-group">
            <%= f.label :title, class: 'control-label' %>
            <%= f.text_field :title, class: 'form-control' %>
        </div>

        <div class="form-group">
            <%= f.label :body, class: 'control-label' %>
            <%= f.text_area :body, class: 'form-control', rows: 6 %>
        </div>

        <%= f.submit 'Save', class: 'btn btn-primary' %>
    <% end %>

Paso 1.4: Añade el Enlace

Pongamos el enlace a esta página en nuestro índice.

/app/views/posts/index.html.erb


    <h1>This is a list of posts</h1>
    <%= link_to 'New Post', new_post_path %>
    <ul>
        <% @posts.each do |p| %>
            <li>
                <h3><%= link_to p.title, post_path(p.id) %></h3>
                <p><%= p.body %></p>
            </li>
        <% end %>
    </ul>

Ahora podemos navegar a la página. Si intentas enviar el formulario, este se colgara ya que tratara de publicar datos para "crear" una acción que no hemos creamos.

Paso 2: Crea una Acción

Abre posts_controller.rb y copia el código de la línea 16 a la línea 30:

/app/controllers/posts_controller.rb


class PostsController < ApplicationController

    def index
        @posts = Post.all
    end

    def show
        @post = Post.find(params[:id])
    end

    def new
        @post = Post.new
    end

    def create
        @post = Post.new(allowed_params)

        if @post.save
            flash[:success] = "Created new post"
            redirect_to @post
        else
            render 'new'
        end
    end

    private
        def allowed_params
            params.require(:post).permit(:title, :body)
        end
end

Escribimos bastante código en unas cuantas líneas. Primero, observa el código bajo la declaración private(todo lo que está en private, sólo está disponible dentro del controlador – una función de seguridad). Aquí definimos allowed_params. Esta es una característica que viene con Rails 4 como estándar de seguridad mejorada. No iremos ahora en detalles de por qué esta hecho así. Lo que tienes que recordar es que tienes que añadir todos los parámetros que están incluidos en el formulario de "permitted". De lo contrario, no se salvaron después de enviarlo.

Ahora, veamos la acción. En la primera línea se puede ver:


@post = Post.new(allowed_params)

Creamos la variable @post y estamos utilizando el metodo new en la clase Post. Pasamos como argumentos allowed_params el cual hemos definido bajo la declaración privada.

El método new no guarda nuestra publicación en la base de datos. En cambio, almacena la publicación en su memoria hasta que decidimos guardarla. Eso, lo haremos en el siguiente paso. Si no podemos guardarla, @post.save se devolverá a falso y la acción reenviara una "nueva" página, si la acción lo logra, recibiremos una notificación de que tuvimos éxito y la acción mostrara la página que nos dirigirá a @post.

¿Por qué no se podría guardar? Quizás el título o el cuerpo estaban vacíos. 

Por el momento no tenemos manera de rechazar ese tipo de envíos. Puedes intentarlo; nuestra aplicación salvará cualquier tipo de registro en este punto. Sin ningún cuerpo o título. Esto no es bueno, así que tenemos que arreglarlo.

Paso 2.2: Agrega Validations en modelo

En este punto, vuelve a nuestro modelo y añade algunas validaciones en él.

/app/models/post.rb


class Post < ActiveRecord::Base
    validates :title, presence: true, length: { minimum: 3 }
    validates :body, presence: true, length: { minimum: 30 }
end

Esto se asegurará de que tanto el título y el cuerpo que estén presentes tengan por lo menos 3 y 30 caracteres respectivamente.

Paso 2.3: Crea nuevos archivos

Ahora, necesitamos asegurarnos de que nuestros usuarios obtendrán notificaciones acerca de los errores, si hay alguno. Para ello, necesitamos construir un mecanismo para mostrar mensajes de error en el formulario. Dentro de  /app/views create new folder and call it "shared". Dentro de esa carpeta, crea un nuevo archivo y llámalo "_error_messages.html.erb". Asegúrate de agregar "_" al principio del nombre del archivo. En el nuevo archivo, copia y pega el siguiente código:

/app/views/shared/_error_messages.html.erb


<% if object.errors.any? %>
    <div id="error_explanation">
        <div class="alert alert-danger alert-dismissable">
            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
            <p><strong>This form contains <%= pluralize(object.errors.count, 'errors') %>.</strong></p>
            <ul>
                <% object.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    </div>
<% end %>

Ahora, podemos volver a nuestro formulario y procesar este "parcial" allí. El código es construido de una manera en que el contenedor de errores sólo aparecerá si se produce un error.

/app/views/posts/new.html.erb


    <%= form_for @post do |f| %>
        <%= render 'shared/error_messages', object: f.object %>
        <div class="form-group">
            <%= f.label :title, class: 'control-label' %>
            <%= f.text_field :title, class: 'form-control' %>
        </div>

        <div class="form-group>
            <%= f.label :body, class: 'control-label' %>
            <%= f.text_area :body, class: 'form-control', rows: 6 %>
        </div>

        <%= f.submit 'Save', class: 'btn btn-primary' %>
    <% end %>

Inténtalo.

Paso 3: Propiedad de Publicación 

El único problema con la configuración anterior es que no hay manera para registrar quien es el autor de la publicación. Ahora cualquiera puede venir a nuestro sitio web y postear incluso cuando ellos no han iniciado su sesión. Esto obviamente no es el comportamiento que estamos buscando. Queremos que los usuarios crean una cuenta primero para poder publicar. Además, para cada entrada, queremos mostrar quién es el autor.

Para hacer referencia a usuarios en el registro de publicaciones, necesitamos agregar una nueva columna a la tabla de mensajes en la base de datos. Esto puede hacerse fácilmente con el generador de Rails para las migraciones. En bash (ventana de terminal):

bash


$ rails generate migration add_user_id_to_posts user_id:integer

Observa cómo pasamos los argumentos al generador - user_id:integer. Rails también recogerá el nombre de la tabla y lo modificara a posts.


      invoke  active_record
      create    db/migrate/20140512101508_add_user_id_to_posts.rb

Echémosle un vistazo el archivo recién creado en migración

db/migrate/20140512101508_add_user_id_to_posts.rb


class AddUserIdToPosts < ActiveRecord::Migration
  def change
    add_column :posts, :user_id, :integer
  end
end

Paso 3.2: Ejecuta Migración

Ahora podemos migrar la base de datos con rake task:

bash


$ rake db:migrate

== 20140512101508 AddUserIdToPosts: migrating =================================
-- add_column(:posts, :user_id, :integer)
   -> 0.0047s
== 20140512101508 AddUserIdToPosts: migrated (0.0048s) ========================

Paso 3.3: Modifica la Publicación y los Archivos de los Usuarios

Ahora, tenemos que saber acerca de la relación existente entre las publicaciones y los usuarios de nuestra aplicación. Añade la línea 4 después de class User < ActiveRecord::Base.

app/models/user.rb


class User < ActiveRecord::Base

  has_many :posts, dependent: :destroy

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

Ahora, agrega la línea 4 en post.rb:

app/models/post.rb


class Post < ActiveRecord::Base

  belongs_to :user

  validates :title, presence: true, length: { minimum: 3 }
  validates :body, presence: true, length: { minimum: 30 }
end

Esas dos líneas has_many y belongs_to nos dan capacidad para crear mensajes "a través del" usuario que automáticamente se inyectará a  user_id en el registro de entradas. Para ver como funciona esto, cambia posts controllers para tomar ventaja de este:

app/controllers/posts_controller.rb


  def create

    @user = current_user
    @post = @user.posts.build(allowed_params)

    if @post.save
      flash[:success] = "Created new post"
      redirect_to @post
    else
      render 'new'
    end
  end

Y también añade el autor a nuestros “views”:

app/views/posts/index.html


    <ul>
        <% @posts.each do |p| %>
            <li>
                <h3><%= link_to p.title, post_path(p.id) %></h3>
                <p><small><strong>By: </strong><%= p.user.email %></small></p>
                <p><%= p.body %></p>
            </li>
        <% end %>
    </ul>

app/views/posts/show.html


    <h1><%= @post.title %></h1>
    <p><small><strong>By: </strong><%= @post.user.email %></small></p>
    <p><%= @post.body %></p>

Paso 4: Ejecuta "Rails Console"

Si intentas recargar la página, verás que se cuelga. Eso es porque los puestos que hemos creado antes no contienen ningún user_id. Así que tenemos que limpiar la base de datos. Abre rails console en la terminal:

bash


$ rails console

2.1.1 :001 > Post.destroy_all

Paso 5: Usa Devise

Antes de empezar a crear las publicaciones, tenemos que hacer un último ajuste. En este momento, estamos usando current_user para crear las publicaciones. Como ya hemos aprendimos current_usersolo se presenta si el usuario está en la sesión. ¿Qué pasa si el usuario no está en la sesión y quiere enviar una nueva publicación? La publicación se colgara. Afortunadamente, es fácil de resolver este problema usando Device.

app/controllers/posts_controller.rb


class PostsController < ApplicationController

    before_filter :authenticate_user!, except: [:show, :index]

    # existing code
end

:authenticate_user!es un método suministrado por Devise. Este permitirá que solo los usuarios que están dentro de la sesión, tengan acceso a todas las acciones, excepto las que especificamos con except. Pero, eso no es todo. Si el usuario intenta tener acceso a una acción restringida, Devise lo enviara directamente a la página de inicio de sesión. Después de iniciar la sesión o registrarse, Devise lo llevara de regreso al lugar donde quería acceder.

¡Inténtalo!

Editing Posts

Si tu Inicio de sesión serás capaz de marcar esto tutorial Como vas avanzando tu progreso



Comentar

Tú puedes Inicio de sesión Comentar