2016-01-13 155 views
2

试图学习RoR。目前正在向用户添加评论。到目前为止,我有一个帖子模型,评论模型和post_comments模型(将两者关联起来)。所以对于 '轨控制台' 我可以运行:(比如我设置P = Post.first和c = Comment.first)Ruby on Rails - 添加评论

p.comments < <Ç

这形成了这样的关联它在控制台中工作。我似乎无法从用户界面中获得评论来形成此关联。到目前为止,我在“comments/new”创建注释(不确定这是否是问题,是否需要在“post”的“show view”中创建)。

下面是一些代码片段

控制器 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 <%的部分= link_to comment.name,comment_path(评论)%>  

最后是新的评论页面,因为它是。

的意见/ 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) 
+0

我认为问题在于,您的'新评论'视图中没有任何地方提及该帖子,因此当您创建评论时,它不会附加到帖子中。这就是说我不明白你为什么使用post_comments关联表,如果评论只属于一个你不需要的帖子。 – taglia

+0

感谢您的回复。是的,这对我有意义。同样在后面的观察,最好是添加一列到帖子数据库的一系列评论? @taglia –

+0

我只是在你的评论表中添加一个post_id列,所以评论属于帖子,帖子会有很多评论。 – taglia

回答

5

作为注释可以属于一个帖子而已,你并不需要一个关联表(post_comments)。你只需要一个简单的一对多关系。

您发表的留言是:

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

和评论会是这样的:

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

只要确保你在comments表的必要post_id列(您可以检查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模板的隐藏字段中。您可以在通过URL传递后在PostsController中设置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参数添加到li st允许的参数CommentsController

+0

这看起来不错。我将执行这些更改并返回结果。再次非常感谢。 –

+0

嘿,我已经实现了所有这些变化,它已经全部建立起来了。唯一的是当我创建一个新的评论并检查控制台时,post_id被设置为零。不知道如何让它看起来对我来说都是正确的。 @taglia –

+1

当你点击“新评论”按钮时,该URL看起来像是“http://your.server.com/comments/new?post_id = 123'?您是否已将'post_id'添加到CommentsController中允许的参数列表中?它应该是'params.require(:comment).permit(:comment,:post_id)'。 – taglia