Rails scope 的一个问题让我很迷惑

wpzero · 2015年05月19日 · 最后由 wpzero 回复于 2015年05月19日 · 1786 次阅读

class Resource
    belongs_to :user
    wfl_mount_file_base :file, ResourceFileBase

    class << self
        attr_reader :cat_hash

        def abs_path parent_path
            WflFileBase.config.root + 'article' + parent_path
        end
    end

    @cat_hash = {
        :article => 1,
        :folder => 11
    }
    scope :cat, ->(*cat_infos){
        where('resources.cat in (?)', cat_infos.map{|cat_info| Resource.cat_hash[cat_info.to_sym] })
    }

    scope :children, ->(parent_info){
        # puts self.to_sql
        if String === parent_info
            where('resources.parent_path = ?', parent_info)
        elsif self === parent_info
            where('resources.parent_path = ?', parent_info.path)
        elsif Fixnum === parent_info
            where('resources.parent_path = ?', Resource.find(parent_info).path)
        elsif Array === parent_info
            where('resources.parent_path in (?)', parent_info.map{|parent_id| Resource.find(parent_id).path})
        else
            none
        end
    }
end

以前没有注意的一个问题,现在也很迷惑,请大家帮我解惑。 Resource.cat(['article']).children([1])(注意:Resource.find(1) 为 folder)。 会报ActiveRecord::RecordNotFound: Couldn't find Resource with 'id'=1 [WHERE (resources.cat in (1))],,我用 rubymine 调试,发现在上面这句话在执行到 children 这个 method 的 context 中时,Resource.all.to_sql 竟然是"SELECT \"resources\". FROM \"resources\" WHERE (resources.cat in (1))" ,我很迷惑前边的 cat(*['article']) 为什么会影响 Resource 的 scope,最后我把 children 改为

scope :children, ->(parent_info){
    # puts self.to_sql
    if String === parent_info
        where('resources.parent_path = ?', parent_info)
    elsif self === parent_info
        where('resources.parent_path = ?', parent_info.path)
    elsif Fixnum === parent_info
        where('resources.parent_path = ?', Resource.unscoped.find(parent_info).path)
    elsif Array === parent_info
        where('resources.parent_path in (?)', parent_info.map{|parent_id| Resource.unscoped.find(parent_id).path})
    else
        none
    end
}

加上 unscoped 才不报错。

WoW,我才知道有 none 这个用法 👍

#1 楼 @rei 我是看一个 ruby-china 兄弟的帖子学的。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号