[RoR] Criando model comment e entendendo relacionamento has_many

14 set 2011(há 13 anos)
DevelopmentRuby on Rails
#validates#routes#relashionship#rake#rails#migration#migrate#helper#has_many#flash_message

Olá pessoal, depois de ter mostrado com gerar e validar um scaffold venho dar continuidade ao projeto que estou estudando, sem muito "bla bla bla" , hoje geraremos um scaffold e faremos os comentarios do Post, tomando cuidado para que os comentarios não fique orfão, let's go...

~/RailsProjects/producer$ rails generate scaffold comment author:string email:string url:string body:text post:references
 width=

Percebam o model do scaffold recém gerado, repare que o model Comment já virá com a linha "belongs_to :post", bem depois disso preciso mapear a outra ponta, vamos abrir o model post e inserir o relacionamento "has_many", porém dessa forma se um post for apagado todos os seus comments irão ficar orfão, por isso é necessário que adicione :dependent => :destroy ou :dependent => :delete porém por padão é aconselhável usar dependent => destroy pois é mais rápido, veja como ficou o post.rb ficou:

class Post < ActiveRecord::Base
  validates_presence_of :title, :body
  has_many :comments, :dependent => :destroy
end

Bom depois disso é necessário fazer a migração do banco de dados rodando um:

rake db:migrate

Agora é hora de nos aperriamos com as rotas, se rodar um "rake routes" veremos todas as rotas/url para minha aplicação, percerbam que é possivel criar um comment sem nenhum post relacionado, porém não é isso que queremos, um comentário só poderá ser criado amarrado à um post, antes de alterar o arquivo routes.rb rode um:

rake routes

Em seguida abra o arquivo routes.rb dentro da pasta config e altere-o de:

resources :comments
resources :posts
get "pages/index"

para:

resources :posts do
  resources :comments, : only => [:create]
end
get "pages/index"

E depois rode mais uma vez:

rake routes

Agora precisamos fazer um refactoring no controller comments e ele ficará:

class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.build(params[:comment])
        flash[:alert] = "Fail to receive the comment. Double check the fields" unless @comment.save
    redirect_to @post
  end
end

Agora iremos fazer algumas validações no model comment é só adicionar o código abaixo no model:

with_options :allow_blank => true do |c|
  c.validates_format_of :email, :with => /A([^@ ]+)@((?:[-a-z0-9]+.)+[a-z]{2,})Z/i
  c.validates_format_of :url,   :with => /^(http|https)://[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?/.*)?$/ix
end

Nosso próximo passo é criar um partial para os comentário



Posted ago

Agora iremos formatar a partial form do post:


50 %>

10, :cols => 80 %>

10, :cols => 80 %>
"Aguarde..." %>

Outra alteração que deverá ser feita é: O campo excerpt foi criado como string mas vou precisar altera-lo para text

~/RailsProjects/producer$ rails g migration change_excerpt_in_post

agora abra o aquivo change_excerpt_in_post e veja que nele há uma class com dois metodos, deixe-o da seguinte forma:

class ChangeExcerptInPost < ActiveRecord::Migration
  def self.up
    change_columm :posts, :excerpt, :text
  end
    def self.down
    change_columm :posts, :excerpt, :string
  end
end

depois rode um:

rake db:migrate

Mudando a view index do Post

|'Are you sure?', :method => :delete %>


We'll start posting soon.

Mudando a view show do Post


Comments


 @post, :comment => Comment.new %>
  |

Vamos editar o application_helper para adicionarmos flash_message

def flash_messages
  flash.collect do |key, msg|
    content_tag(:p, msg, :id => key, :class => "flash_message")
  end.join.html_safe
end

no layout chamaremos flash_messages

Producer

Por fim é necessário rodar um rake db:migrate

rake db:migrate

conclusão

Bem depois dos passos acima é só correr para o abraço e ver se Funfou, caso precise do código para verificar se para comparação clique aqui e mas antes de testar é necessário rodar um rake db:migrate. Continua...