简体   繁体   English

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

[英]Ruby on Rails - nested associations - creating new records

I'm learning Rails (4.2 installed) and working on a social network simulation application. 我正在学习Rails(已安装4.2)并致力于社交网络仿真应用程序。 I have setup an one to many relation between Users and Posts and now I'm trying to add also Comments to posts. 我已经在“用户”和“帖子”之间建立了一对多关系,现在我正尝试在帖子中添加“评论”。 After multiple tries and following the documentation on rubyonrails.org I ended up with the following setup: 经过多次尝试并遵循rubyonrails.org上文档,我最终进行了以下设置:

User Model 用户模型

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

Post Model 邮政模型

  belongs_to :user
  has_many :comments

Comment Model 评论模型

  belongs_to :user

The comment is initiated from the Post show page, so the Post Controller has: 该评论是从发布秀页面开始的,因此发布控制器具有:

def show
    @comment = Comment.new
  end

Now the question is: in Comments Controller , what is the correct way to create a new record. 现在的问题是:在Comments Controller中 ,创建新记录的正确方法是什么。 I tried the below and many others, but without success. 我尝试了以下方法和许多其他方法,但均未成功。

def create

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

    redirect_to users_path

  end

(current_user is from Devise) (current_user来自Devise)

Also, afterwards, how can I select the post corresponding to a comment? 此外,之后,如何选择与评论相对应的帖子?

Thank you 谢谢

You'll want to create a relation on Post , letting each Comment know "which Post it relates to." 您将要在Post上创建一个关系,让每个Comment知道“它与哪个Post相关”。 In your case, you'll likely want to create a foreign key on Comment for post_id , then each Comment will belong_to a specific Post . 在您的情况下,您可能需要在Commentpost_id创建一个外键,然后每个Commentbelong_to一个特定的Post So, you'd add belongs_to :post on your Comment model. 因此,您将在Comment模型上添加belongs_to :post

So, your models become: 因此,您的模型变为:

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

Then, to create a Comment , you would want to do one of two things in your controller: 然后,要创建Comment ,您需要在控制器中执行以下两项操作之一:

  1. Load the Post corresponding to the Comment you are creating via the URI as a parameter. 通过URI加载与您正在创建的Comment相对应的Post作为参数。

  2. Pass the Post ID along in the form in which calls the create method on Comment . Post ID传递给在Comment上调用create方法的表单。

I personally prefer loading the Post from a parameter in the URI, as you'll have less checking to do as far as authorization for can the Comment in question be added to the Post - eg think of someone hacking the form and changing the ID for the Post that the form originally sets. 我个人更喜欢从URI中的参数加载Post ,因为您可以做的检查很少,只要可以将有问题的Comment添加到Post -例如,想到有人入侵表单并更改ID表单最初设置的Post

Then, your create method in the CommentsController would look like this: 然后, 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

Change your Comment model into: 将您的Comment模型更改为:

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

Pass the post_id from view template: 从视图模板传递post_id

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

Then change your create action: 然后更改您的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM