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?
,而不能看到只需通过的.post_is_mine
,因为它返回TRUE
我尝试了其他几个名称作为方法,因为有些东西可能导致问题,甚至只是用 .post_is_mine 尝试if语句但仍然没有运行查询
关于我如何使用where子句,模型是否存在问题?
答案 0 :(得分:4)
是。 #where
返回ActiveRecord Relation,用于生成查询。您的代码中不会评估该关系,因此永远不会执行.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
编辑:
我很好奇我的回答与Pavling的答案之间的区别。对于其他任何想知道:
#exists?
使用SELECT 1 FROM ...
#any?
使用SELECT COUNT(*) FROM ...
在实践中,两者之间可能差别不大,但是一些粗略的基准测试表明#any?
更快(在OSX上使用AR 3.2.6和Postgresql 9.1)
答案 1 :(得分:1)
“where”将返回一个空集合,其评估为真实。您需要添加一个检查,以查看其中是否有任何记录以获得正确的错误。
def self.post_is_mine(post_id, user_id)
where("user_id = ? and post_id = ?", user_id, bucket_id).any?
end