我正在关注这个简单博客的在线视频(here)教程。
这些博文中有评论。
在本教程中,使用了Devise gem并执行了迁移以将post user_id分配给帖子。
我进行了add_user_id_to_comments的迁移,类似于在帖子的user_id迁移中完成的迁移。
class AddUserIdToComments < ActiveRecord::Migration
def change
add_column :comments, :user_id, :integer
add_index :comments, :user_id
end
end
我的模型包含以下内容:
评论模型
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
用户模型
class User < ActiveRecord::Base
has_many :posts
has_many :comments
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
我可以为执行以下操作的用户分配评论。
user = User.first
comment = Comment.first
comment.user = user
这适用于控制台,但我遇到的问题是comments_controller。 我试图模仿使用后置控制器完成的步骤。
这是来自帖子控制器(工作正常)
class PostsController < ApplicationController
before_action :find_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
before_action :post_auth, only: [:edit, :update, :destroy]
def index
@posts = Post.all.order('created_at DESC')
end
def new
#@post = Post.new
@post = current_user.posts.build
end
def create
#@post = Post.new(post_params)
@post = current_user.posts.build(post_params)
if @post.save
redirect_to @post
else
render 'new'
end
end
def show
end
def edit
end
def update
if @post.update(params[:post].permit(:title, :body))
redirect_to @post
else
render 'edit'
end
end
def destroy
@post.destroy
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:title, :body)
end
def find_post
@post = Post.find(params[:id])
end
# Checks if current user authored pin
def post_auth
if current_user != @post.user
redirect_to(root_path)
end
end
end
评论控制器我在
方面遇到了困难class CommentsController < ApplicationController
before_action :find_comment, only: [:create, :destroy]
before_action :comment_auth, only: [:destroy]
def create
#@post = Post.find(params[:post_id])
#@comment = @post.comments.create(params[:comment].permit(:name, :body))
#redirect_to post_path(@post)
#new format
@post = Post.find(params[:post_id])
#post = current_user.posts.build(post_params)
@comment = current_user.comments.build(comment_params)
redirect_to post_path(@post)
end
def destroy
@comment = @post.comments.find(params[:id]).destroy
redirect_to post_path(@post)
end
private
def comment_params
params.require(:comment).permit(:name, :body)
end
def find_comment
@post = Post.find(params[:post_id])
end
def comment_auth
if current_user != @post.user
redirect_to(root_path)
end
end
end
当我尝试创建新评论时;没有任何反应......它重定向到帖子页面。 但是没有返回任何错误。
您的想法如何解决此问题? 任何帮助将不胜感激。
编辑w / SOLUTION
我遇到的问题是&#39; 名称和正文值未传递到数据库。经过多次尝试,我终于能够使用以下代码传递名称和 body 值:
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment].permit(:name, :body))
@comment.user_id=current_user.id if current_user
@comment.save
if @comment.save
redirect_to post_path(@post)
else
render 'new'
end
谢谢大家的帮助
答案 0 :(得分:2)
@comment = current_user.comments.build(comment_params)
您在评论中致电build
,然后不保存。您需要save
或使用create
。
答案 1 :(得分:1)
使用build
方法时,会返回一个对象,但尚未将其保存到数据库中。您有两种选择:
手动保存对象:
@post = Post.find(params[:post_id])
@comment = current_user.comments.build(comment_params)
@comment.save!
redirect_to post_path(@post)
或
使用自动保存的create
方法(请注意,我没有对此进行测试,如果我说谎,请提供反馈!)
@post = Post.find(params[:post_id])
@comment = current_user.comments.create(comment_params)
redirect_to post_path(@post)
在Rails docs(强调我的)中看到两者之间的差异:
collection.build(attributes = {}, …)
返回一个或多个集合类型的新对象,这些对象已使用属性进行实例化,并通过外键链接到此对象,但尚未保存。
collection.create(attributes = {})
返回已使用属性实例化的集合类型的新对象,通过外键链接到此对象,已保存(如果它已通过验证)。注意:这仅适用于数据库中已存在基本模型的情况,而不是新的(未保存的)记录!
答案 2 :(得分:0)
class CommentsController < ApplicationController
# Omitted some code code
def create
#@post = Post.find(params[:post_id])
#@comment = @post.comments.create(params[:comment].permit(:name, :body))
#redirect_to post_path(@post)
#new format
@post = Post.find(params[:post_id])
#post = current_user.posts.build(post_params)
@comment = current_user.comments.build(comment_params)
redirect_to post_path(@post)
end
# Omitted more code
end
在创建操作中,您没有保存@comment
,而只是构建它。您应该致电@comment.save
或current_user.comments.create(comment_params)
。为了说明我的意思:
要么:
def create
@post = Post.find(params[:post_id])
@comment = current_user.comments.create(comment_params)
redirect_to post_path(@post)
end
或者,这将有效。
def create
@post = Post.find(params[:post_id])
@comment = current_user.comments.build(comment_params)
@comment.save # returns true if save successful, false otherwise
redirect_to post_path(@post)
end
答案 3 :(得分:0)
我是一名学习者,甚至我已经创建了相同的应用程序并找到了方法,只需检查它是否有帮助。解决方案是将merge()添加到参数中
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body).merge(user_id: current_user.id)
end