Ruby on Rails - 添加评论以发布

时间:2016-01-13 02:00:14

标签: ruby-on-rails comments

尝试学习RoR。目前正在向用户添加评论。到目前为止,我有一个帖子模型,评论模型和post_comments模型(将两者联系起来)。所以对于'rails console',我可以运行:(比如我设置p = Post.first和c = Comment.first)

  

p.comments<< ç

这形成了一个关联,因此它可以在控制台中运行。我似乎无法从UI中获得用于形成此关联的注释。到目前为止,我正在“评论/新”创建评论(不确定这是否是问题。是否需要在“发布视图”上创建“发布”)。

以下是一些代码段

  

控制器   comments_controller.rb

class CommentsController < ApplicationController

def index
  @comment = Comment.all
end

def new
  @comment = Comment.new
end

def create
  @comment = Comment.new(commentParams)
  if @comment.save
    flash[:success] = "Comment successfully added"
    redirect_to comments_path(@comment)
  else
    render 'new'
  end
end

def show
  @comment = Comment.find(params[:id])
end

private

  def commentParams
    params.require(:comment).permit(:comment)
  end
end
  

posts_controller

class PostsController < ApplicationController
before_action :setPost, only: [:edit, :update, :show, :destroy, :sold]
before_action :requireUser, except: [:index, :show]
before_action :requireSameUser, only: [:edit, :update, :destroy, :sold]

def index
  @posts = Post.paginate(page: params[:page], per_page: 20)
end

def new
  @post = Post.new
end

def create
  @post = Post.new(postParams)
  @post.user = currentUser
  if @post.save
    flash[:success] = "Post successfully added."
    redirect_to post_path(@post)
  else
    render 'new'
  end
end

def update
  if @post.update(postParams)
    flash[:success] = "Post successfully updated."
    redirect_to post_path(@post)
  else
    render 'edit'
  end
end

def show
end

def edit
end

def sold
  @post.toggle(:sold)
  @post.save
  redirect_to post_path(@post)
end

def destroy
  @post.destroy
  flash[:danger] = "Item successfully deleted."
  redirect_to posts_path
end

private
  def postParams
    params.require(:post).permit(:title, :price, :description,   category_ids:[])
  end

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

  def requireSameUser
    if currentUser != @post.user and !currentUser.admin
      flash[:danger] = "You can only edit or delete your own items"
      redirect_to root_path
    end
  end
end
  

模型   comment.rb

class Comment < ActiveRecord::Base
  belongs_to :post_comments
  belongs_to :user
  belongs_to :post
end
  

post_comment.rb

class PostComment < ActiveRecord::Base
  belongs_to :post
  belongs_to :comment
end
  

post.rb

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :post_categories
  has_many :categories, through: :post_categories
  has_many :post_comments
  has_many :comments, through: :post_comments  

  validates :title, presence: true,
                length: { minimum: 4, maximum: 20 }

  validates :description, presence: true,
                      length: { maximum: 1000 }
  validates :user_id, presence: true

  

浏览   文章/ show.html.erb

  <p>Comments: <%= render @post.comments %></p>

这会将部分呈现在

之下
  

评论/ _comment.html.erb   &lt;%= link_to comment.name,comment_path(comment)%&gt;

最后是新的评论页面。

  

评论/ new.html.erb

<h1>New Comment</h1>

<%= render 'shared/errors', obj: @comment %>

<div class="row">
<div class="col-xs-12">
  <%= form_for(@comment, :html => {class: "form-horizontal", role: "form"}) do |f| %>

  <div class="form-group">
    <div class="control-label col-sm-2">
      <%= f.label :comment %>
    </div>

    <div class="col-sm-8">
      <%= f.text_area :comment, rows: 3, class: "form-control", placeholder: "Please enter a comment", autofocus: true %>
    </div>
  </div>

  <div class="form-group">
    <div class="center col-sm-offset-1 col-sm-10">
      <%= f.submit class: "btn btn-primary btn-lg" %>
    </div>
  </div>
<% end %>

任何帮助都会受到极大的欢迎。

更新

  

日志

Started GET "/posts/2" for ::1 at 2016-01-15 12:39:55 +0000
Processing by PostsController#show as HTML
Parameters: {"id"=>"2"}
[1m[36mPost Load (0.1ms)[0m  [1mSELECT  "posts".* FROM "posts" WHERE    "posts"."id" = ? LIMIT 1[0m  [["id", 2]]
[1m[35mUser Load (0.1ms)[0m  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
[1m[36m (0.1ms)[0m  [1mSELECT COUNT(*) FROM "posts" WHERE "posts"."user_id" = ?[0m  [["user_id", 1]]
[1m[35mCategory Exists (0.1ms)[0m  SELECT  1 AS one FROM "categories"    INNER JOIN "post_categories" ON "categories"."id" =  "post_categories"."category_id" WHERE "post_categories"."post_id" = ?  LIMIT 1  [["post_id", 2]]
[1m[36mCategory Load (0.0ms)[0m  [1mSELECT "categories".* FROM "categories" INNER JOIN "post_categories" ON "categories"."id" = "post_categories"."category_id" WHERE "post_categories"."post_id" = ?[0m  [["post_id", 2]]
Rendered categories/_category.html.erb (0.2ms)
[1m[35mComment Load (0.1ms)[0m  SELECT "comments".* FROM "comments"  WHERE "comments"."post_id" = ?  [["post_id", 2]]
Rendered comments/_comment.html.erb (0.1ms)
Rendered posts/show.html.erb within layouts/application (6.5ms)
[1m[36mCategory Load (0.1ms)[0m  [1mSELECT "categories".* FROM "categories"[0m
Rendered layouts/_navigation.html.erb (0.9ms)
Rendered layouts/_messages.html.erb (0.1ms)
Rendered layouts/_footer.html.erb (0.1ms)
Completed 200 OK in 52ms (Views: 50.3ms | ActiveRecord: 0.5ms)

2 个答案:

答案 0 :(得分:7)

由于评论只能属于一个帖子,因此您不需要关联表(post_comments)。你只需要一个简单的一对多关系。

您的帖子评论将是:

class Post < ActiveRecord::Base
  has_many :comments
  ...
end

评论会是这样的:

class Comment < ActiveRecord::Base
  belongs_to :post
  ...
end

只需确保post_id表中有必要的comments列(您可以查看db/schema.rb文件)。如果缺少,可以使用以下迁移添加它:

class AddPostIdToComments < ActiveRecord::Migration
  def change
    add_column :comments, :post_id, :integer
    add_index  :comments, :post_id
  end
end

每当用户尝试为帖子创建评论时,您还需要确保保留对帖子的引用。您可以在隐藏字段中将其添加到comments/new.html.erb模板中。您可以在PostsController中通过URL传递new操作中的隐藏字段。

因此,在您的posts/show.html.erb模板中,您将拥有:

<%= link_to "Add Comment", new_comment_path(post_id: @post.id) %>

new行动中PostsController

def new
  @comment = Comment.new(post_id: params[:post_id])
end

最后,您表单中隐藏的字段将是:

<%= f.hidden_field :post_id %>

最后,将post_id参数添加到CommentsController中的允许参数列表中。

答案 1 :(得分:0)

代替

在您的新操作中,在PostsController中:

def new
    @comment = Comment.new(post_id: params[:post_id])
end

您可以在表单视图中使用它

<%= form.hidden_field :post_id, value: "#{params[:post_id]}" %>