0

posts_controller.rb 销毁方法

def destroy

    if !request.xhr?
        render_404
        return
    end

    if user_signed_in?

        if Post.exists?(:post_id => params[:id])

                if Post.post_is_mine(params[:id], current_user.id)

                    @return = { :error => false, :response => "Post deleted" }

                else
                    @return = { :error => true, :response => 'You are not allowed to perform this action.' }
                end

            else
                @return = { :error => true, :response => 'This post doesn\'t exist.' }
            end

        else
            @return = { :error => true, :response => 'Please login before you delete a post.' }
        end

    render :json => ActiveSupport::JSON.encode( @return )

end

post.rb

  def self.post_is_mine(post_id, user_id)
    #where(:user_id => user_id, :post_id => bucket_id)
    where("user_id = ? and post_id = ?", user_id, bucket_id)
  end

当我在销毁帖子时检查正在运行的查询时,我只能看到.exists?要运行的查询,但不能看到它返回 TRUE 时.post_is_mine简单通过的查询

我尝试了其他几个名称作为方法,因为某些东西可能会导致问题,甚至只是尝试使用.post_is_mine的 if 语句,但仍然没有运行查询

关于我如何使用 where 子句的模型是否存在问题?

4

2 回答 2

4

是的。 #where返回一个 ActiveRecord 关系,用于生成您的查询。该关系不会在您的代码中进行评估,因此.post_is_mine永远不会执行查询。 if Post.postis mine(params[:id], current_user.id)返回true是因为 Relation 对象不是nil

你真正想要的是exists?post_is_mine方法中使用。

def self.post_is_mine(post_id, user_id)
  exists?(:user_id => user_id, :post_id => bucket_id)
end

编辑:

我很好奇我的答案和帕夫林的答案之间的区别。对于其他想知道的人:

#exists?执行一条 SQL 语句SELECT 1 FROM ...

#any?执行一条 SQL 语句SELECT COUNT(*) FROM ...

在实践中,两者之间可能没有太大区别,但一些粗略的基准表明#any?速度更快(在 OSX 上使用 AR 3.2.6 和 Postgresql 9.1)

于 2012-08-18T08:27:41.460 回答
1

“where”将返回一个空集合,其评估为真。您需要添加一个检查以查看其中是否有任何记录以获得正确的真/假。

def self.post_is_mine(post_id, user_id)
  where("user_id = ? and post_id = ?", user_id, bucket_id).any?
end
于 2012-08-18T08:27:24.610 回答