【问题标题】:Assigning Devise current_user to comment分配设计 current_user 以发表评论
【发布时间】:2015-04-09 03:37:07
【问题描述】:

我正在关注这个在线视频 (here) 教程以获取一个简单的博客。

这些博文中包含 cmets。

在本教程中,使用了 Devise gem 并执行了迁移以将添加 user_id 分配给帖子。

我做了一个 add_user_id_to_cmets 的迁移,类似于在帖子的 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

这在控制台中有效,但我遇到的问题是 cmets_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

当我尝试创建新评论时;什么都没有发生...它重定向到帖子页面。 但是没有返回任何错误。

您的想法如何解决这个问题? 任何帮助将不胜感激。

使用解决方案编辑

我遇到了 'namebody 值未传递到数据库的问题。经过几次尝试,我终于能够使用以下代码传递 namebody 值:

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

谢谢大家的帮助

【问题讨论】:

  • 感谢您的回复。虽然 cmets 被保存到数据库,但 post_id 并没有被传递到数据库。在数据库中,post_id 为 NULL。我尝试过以下操作:@comment = @post.current_user.comments.build(comment_params) 请告知。

标签: ruby-on-rails ruby devise


【解决方案1】:
@comment = current_user.comments.build(comment_params)

您在您的 cmets 上调用 build,然后没有保存它们。您要么需要save,要么使用create

【讨论】:

    【解决方案2】:

    当您使用build 方法时,会返回一个对象,但它尚未保存到数据库中。你有两个选择:

    1. 手动保存对象:

      @post = Post.find(params[:post_id])
      @comment = current_user.comments.build(comment_params)  
      @comment.save!  
      redirect_to post_path(@post)    
      

      或者,

    2. 使用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 = {})
    

    返回一个集合类型的新对象,该对象已经用属性实例化,通过外键链接到该对象,并且已经保存(如果它通过了验证)。注意:这仅适用于数据库中已存在基本模型的情况,而不是新的(未保存的)记录!

    【讨论】:

      【解决方案3】:
      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.savecurrent_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   
      

      【讨论】:

        【解决方案4】:

        我是一个学习者,即使我已经创建了相同的应用程序并找到了方法,请检查它是否有帮助。解决方案是将merge()添加到params

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-06
          • 1970-01-01
          • 2020-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多