[RoR] Criando model comment e entendendo relacionamento has_many
14 set 2011(há 14 anos)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
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 %>
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...