【问题标题】:Ruby on Rails - nested associations - creating new recordsRuby on Rails - 嵌套关联 - 创建新记录
【发布时间】:2015-03-17 05:40:55
【问题描述】:

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

用户模型

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

后模型

  belongs_to :user
  has_many :comments

评论模型

  belongs_to :user

评论是从 Post show 页面发起的,所以 后控制器拥有:

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)

另外,之后,如何选择评论对应的帖子?

谢谢

【问题讨论】:

  • current_user.posts 是帖子的集合。 has_many 关联位于单个帖子上,而不是它们的集合。 (编辑:我应该作为答案提交。)

标签: ruby-on-rails ruby-on-rails-4 has-many-through


【解决方案1】:

您需要在Post 上创建一个关系,让每个Comment 知道“它与哪个Post 相关”。在您的情况下,您可能希望在Comment 上为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

【讨论】:

  • 非常感谢!非常详细和专业的答案。只是看看我是否正确: 1. 这是使用 simple_form 在 URL 中传递参数的正确方法吗? simple_form_for(@comment, url: comments_path(@comment, post_id: @post.id)) do |f| 2. 在 CommentsController 中,@comment.save 之前,我必须添加用户,否则不会保存。那是对的吗? @comment = @post.comments.build(comment_params) @comment.user = current_user 再次感谢!
  • 是的,这听起来很正确。我没用过simple_form,但我相信是对的。
【解决方案2】:

将您的 Comment 模型更改为:

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

从视图模板中传递post_id

&lt;%= hidden_field_tag 'post_id', @post.id %&gt;

然后更改您的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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多