Thêm tính năng gửi bình luận

Giả định rằng bạn đã xây dựng một ứng dụng Rails Girl bằng cách làm theo hướng dẫn cơ bản đầu tiên

1. Tạo comment scaffold

Tạo một scaffold cho comment, với tên người comment, body của comment (nội dung comment) và tham chiếu (liên kết) đến bảng ideas (idea_id)

rails g scaffold comment user_name:string body:text idea_id:integer

Coach

Sau khi sử dụng câu lệnh , sẽ tạo ra:

  1. Tập tin migration báo cho cơ sở dữ liệu của bạn (database) biết về bảng comments mới được tạo ra.
  2. Mội tập tin idea.rb được sinh ra trong thư mục app/model để thao tác với CSDL
  3. Một controller để điều khiển viêc thao tác
  4. Tạo router
  5. Tạo một thư mục trong view có tên ideals

Sử dụng lệnh sau để chạy các tệp tin migrations

rails db:migrate

Khi đó, trong file schema.rb sẽ sinh ra bảng ideal trong cơ sở dữ liệu của bạn

2. Thêm các quan hệ vào các models

Bạn cần phải chắc chắn một điều rằng Rails biết được mỗi quan hệ giữa các đối tượng với nhau (2 đối tượng ở đây là ideascomments). Vì một idea có thể có nhiều comments nên chúng ta cần đảm bảo rằng model idea biết được điều đó. Mở tập tin app/models/idea.rb và sau dòng

class Idea < ActiveRecord::Base

Thêm vào

has_many :comments

Comment cũng cần phải biết rằng nó thuộc về một idea nào đó. Nên hãy mở tập tin app/models/comment.rb và sau dòng

class Comment < ActiveRecord::Base

Thêm vào

belongs_to :idea

3. Hiển thị form thêm comment và các comment đã tồn tại

Mở tập tin app/views/ideas/show.html.erb và sau image_tag

<%= image_tag(@idea.picture_url, :width => 600) if @idea.picture.present? %>

Thêm vào

<h3>Comments</h3>
<% @comments.each do |comment| %>
  <div>
    <strong><%= comment.user_name %></strong>
    <br />
    <p><%= comment.body %></p>
    <p><%= link_to 'Delete', comment_path(comment), method: :delete, data: { confirm: 'Are you sure?' } %></p>
  </div>
<% end %>
<%= render 'comments/form' %>

Trong app/controllers/ideas_controller.rb thêm vào action show các dòng sau

@comments = @idea.comments.all
@comment = @idea.comments.build

Mở tập tin app/views/comments/_form.html.erb và sau các dòng sau

<%= form_for(@comment) do |f| %>

thêm vào dòng sau

<%= f.hidden_field :idea_id %>

Và tiếp theo là xóa các dòng sau

<div class="field">
  <%= f.label :idea_id %><br>
  <%= f.number_field :idea_id %>
</div>

Vậy là đã hoàn thành. Bây giờ bạn có thể xem một Idea mà bạn đã thêm vào ứng dụng của bạn trước đây và ở đó bạn sẽ thấy một biểu mẫu để thêm vào các Comments mới cũng như là xóa các comments cũ.

Những câu hỏi nâng cao

1. Dễ

Mở tệp tin app/controllers/comments_controller.rb trong hàm create thay thế dòng sau
format.html { redirect_to @comment, notice: 'Comment was successfully created.' }
bằng dòng sau
format.html { redirect_to idea_path(@comment.idea_id), notice: 'Comment was successfully created.' }

Trong cửa sổ dòng lệnh gõ lệnh sau
rails generate migration AddLikeCountToComments like_count:integer
rake db:migrate

Trong cửa sổ dòng lệnh gõ lệnh sau
rails generate migration AddPictureToComments picture:string
rake db:migrate

Mở tệp tin app/models/comment.rb và thêm vào dòng sau
validates_presence_of :user_name, :body

Trong cửa sổ dòng lệnh gõ
rails generate migration AddReplyIdToComments reply_id:integer
rake db:migrate

2. Bình thường

Mở tệp tin app/models/comment.rb và thêm vào dòng sau
mount_uploader :picture, PictureUploader
Mở tệp tin app/views/comments/_form.html.erb và thêm vào dòng sau
<div class="field">
  <%= f.label :picture %><br>
  <%= f.file_field :picture %>
</div>
Nếu có lỗi xảy ra, hãy thay đổi dòng sau
<%= form_for(@comment) do |f| %>
thành
<%= form_for @comment, :html => {:multipart => true} do |f| %>
Mở tệp tin app/controllers/comments_controller.rb và thay đổi dòng sau
def comment_params
   params.require(:comment).permit(:user_name, :body, :idea_id)
end
thành dòng sau
def comment_params
   params.require(:comment).permit(:user_name, :body, :idea_id, :picture)
end

Mở tệp tin app/controllers/ideas_controller.rb trong hàm show thay thế dòng sau
@comments = @idea.comments.all
bằng
@comments = @idea.comments.order(like_count: :desc).all

Mở tệp tin app/controllers/comments_controller.rb trong hàm create bên dưới dòng
@comment = Comment.new(comment_params)
thêm vào dòng sau
@idea = Idea.find_by_id @comment.idea_id
@comments = @idea.comments.all
Thay đổi mã sau
respond_to do |format|
  if @comment.save
     format.html { redirect_to @comment, notice: 'Comment was successfully       created.' }
     format.json { render :show, status: :created, location: @comment }
else
    format.html { render :new }
    format.json { render json: @comment.errors, status: :unprocessable_entity }
  end
end
thành
respond_to do |format|
  if @comment.save
    format.html { redirect_to @comment, notice: 'Comment was successfully created.' }
    format.json { render :show, status: :created, location: @comment }
  else
    format.html { render :template => "ideas/show" }
    format.json { render json: @comment.errors, status: :unprocessable_entity }
  end
end

3. Khó