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

投稿を破棄するときにどのクエリが実行されているかを確認すると、実行するクエリのみが表示されますが、 TRUE が返されるため単に通過するクエリは表示され.exists?ません.post_is_mine

何かが問題を引き起こす可能性があるため、または単純に.post_is_mineで if ステートメントを試してみても、メソッドとして他の名前をいくつか試しましたが、それでもクエリは実行されませんでした

where句の使用方法に関して、モデルに問題がある可能性はありますか?

4

2 に答える 2

4

はい。 #whereクエリの生成に使用される ActiveRecord リレーションを返します。リレーションはコードで評価されないため、クエリは.post_is_mine実行されません。 Relation オブジェクトが ではないため、if Post.postis mine(params[:id], current_user.id)が返されます。truenil

本当に欲しいのは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?でSQL文を実行しますSELECT 1 FROM ...

#any?でSQL文を実行しますSELECT COUNT(*) FROM ...

実際には、この 2 つの間に大きな違いはない可能性がありますが、いくつかの大まかなベンチマークでは#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 に答える