Ruby 在 Rails - 嵌套关联 - 创建新记录

Ruby on Rails - nested associations - creating new records

我正在学习 Rails(已安装 4.2)并开发社交网络模拟应用程序。 我已经在 Users 和 Posts 之间建立了一对多的关系,现在我正在尝试向 posts 添加评论。经过多次尝试并遵循 documentation on rubyonrails.org 我最终得到了以下设置:

用户模型

  has_many :posts, dependent: :destroy
  has_many :comments, through: :posts

Post 型号

  belongs_to :user
  has_many :comments

评论模型

  belongs_to :user

评论是从Post展示页面发起的,所以 Post 控制器 有:

def show
    @comment = Comment.new
  end

现在的问题是:在Comments Controller中,创建新记录的正确方法是什么。 我尝试了以下和许多其他方法,但没有成功。

def create

    @comment = current_user.posts.comment.new(comment_params)
    @comment.save

    redirect_to users_path

  end

(current_user 来自 Devise)

还有,以后怎么才能select一个评论对应的post呢?

谢谢

您需要在 Post 上创建一个关系,让每个 Comment 知道 "which Post it relates to." 在您的情况下,您可能需要在 [=] 上创建一个外键13=] 对于 post_id,那么每个 Commentbelong_to 一个特定的 Post。因此,您需要在 Comment 模型上添加 belongs_to :post

因此,您的模型变为:

class User < ActiveRecord::Base
  has_many :posts, dependent: :destroy
  has_many :comments, through: :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

class Comments < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

然后,要创建 Comment,您需要在控制器中执行以下两项操作之一:

  1. 通过 URI 加载与您正在创建的 Comment 相对应的 Post 作为参数。

  2. 以调用 Comment 上的 create 方法的形式传递 Post ID。

我个人更喜欢从 URI 中的参数加载 Post,因为就可以将有问题的 Comment 添加到 Post - 例如想想有人破解了表单并更改了表单最初设置的 Post 的 ID。

然后,CommentsController 中的 create 方法将如下所示:

def create
  @post = Post.find(post_id_param)

  # You'll want authorization logic here for
  # "can the current_user create a Comment
  # for this Post", and perhaps "is there a current_user?"

  @comment = @post.comments.build(comment_params)

  if @comment.save
    redirect_to posts_path(@post)
  else
    # Display errors and return to the comment
    @errors = @comment.errors
    render :new
  end
end


private

def post_id_param
  params.require(:post_id)
end

def comment_params
  params.require(:comment).permit(...) # permit acceptable Comment params here
end

将您的 Comment 模型更改为:

class Comment < ActiveRecord::Base
  belongs_to :post
  belongs_to :user, through: :post
end

从视图模板传递 post_id

<%= hidden_field_tag 'post_id', @post.id %>

然后更改您的 create 操作:

def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.build(comment_params)
  @comment.user = current_user
  redirect_to post_path(@post)
end