Rails源码阅读(四)with_scope and named_scope
with_scope的用法
简而言之,with_scope的用法类似于with_options,能够在内层方法调用的时候,插入外层的条件。有点也类似,可以节省代码。with_scope的作用要多于with_options,这个在named_scope中就会看见了。
这个例子可以看见,外层的查询条件加入了内层的查询条件中,起到了联合查询的目的。
class Article < ActiveRecord::Base
def self.find_with_scope
with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }, :create => { :blog_id => 1 }) do
with_scope(:find => { :limit => 10 })
find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10
end
with_scope(:find => { :conditions => "author_id = 3" })
find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1
end
end
end
end
with_scopde是怎么实现的,代码研究
with_scope的源码比较长,就不粘贴了。
with_scope是个protected方法,实现过程是把参数保存在scope中,等最后查询(find)的时候,再取出scope中保存的条件来,加入find查询的条件中,起到了联合查询的作用。
见find的源码:
def construct_finder_sql(options)
scope = scope(:find)
sql = "SELECT #{options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))} "
sql << "FROM #{options[:from] || (scope && scope[:from]) || quoted_table_name} "
add_joins!(sql, options[:joins], scope)
add_conditions!(sql, options[:conditions], scope)
add_group!(sql, options[:group], options[:having], scope)
add_order!(sql, options[:order], scope)
add_limit!(sql, options, scope)
add_lock!(sql, options, scope)
sql
end
scope 有个技巧,当前要存入scope的条件存入了当前线程的hash中,并且名字为当前的类名相关。
这个是不是很像Hibernate中使用的ThreadLocal阿~
def scoped_methods #:nodoc:
Thread.current[:"#{self}_scoped_methods"] ||= self.default_scoping.dup #self.default_scoping = []
end
另外注意,scoped_methods不会一直增长下去,而是用完就删除了!
self.scoped_methods << method_scoping
begin
yield #查询
ensure
self.scoped_methods.pop #查询完了,就删除了
end
举个例子:
class Tag < ActiveRecord::Base
named_scope :red, :conditions => "id <= 10" do
def dom_id
'red_shirts'
end
end
with_scope(:find => {:conditions => "id <= 5"}) do
with_scope(:find => {:conditions => "id <= 4"}) do #用了两次哦!
find(:all)
end
end
end
这样在使用Tag.red的时候,跟踪下变量:
####这个是with_options存储的,可以看见,条件叠加了,都存储了下来
hash={:find=>{:conditions=>"(id <= 5) AND (id <= 4)"}}
####
####scope中存储的
scoped_methods=[{:find=>{:conditions=>"id <= 5"}}, nil]
####
参考:
http://muyu.iteye.com/blog/248400
http://xf986321.iteye.com/blog/413332
待续
分享到:
相关推荐
Rails_Recipes_with_Source_Code
agile_web_development_with_rails_3rd_edition.9994652073.pdf
RestFul_Rails_Dev_v_0.1 RestFul_Rails_Dev_v_0.1
Agile Web Development with Rails 1-14节_ppt(老师发的修正版)
Rails_3_Cheat_Sheets.pdf
rails_api_with_controller
介绍插件,用于对记录进行排序(使用 gem)安装要启用rails_admin_acts_as_list,请将以下内容添加到您的Gemfile : gem 'rails_admin_acts_as_list'gem 'rails_admin' 重要提示: rails_admin_acts_as_list之前必须...
RailsAdmin_ImageManager RailsAdmin和CKEditor的图像管理器。...$ rails db:migrate SCOPE=rails_admin_image_manager 安装图像管理器CKEditor插件 mkdir -p app/assets/javascripts/ckeditor && touch app
应用Rails进行REST 开发 ,翻译自《RESTful Rails Development》
$ git clone git@github.com:bigardone/rails_with_webpack_starter_kit.git $ bundle install $ npm install -g webpack $ npm install $ rake db:create $ rake db:setup $ foreman start -f Procfile.dev 测试 ...
awesome-rails-gem-zh_CN, Rails 常用 Gem 列表 - Awesome Rails Gem 中文版
自述文件该自述文件通常会记录启动和... 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...rails_6_test_app_with_1_ws_channel
Web开发敏捷之道应用Rails进行敏捷Web开发_中文书_第4版
gem 'rails_admin_content_builder' 运行生成器并进行迁移 rails g rails_admin_content_builder rake db:migrate 在app / assets / application.scss中添加样式 * = require rails_admin_content_builder 用法 ...
自述文件版本和设置$ ruby -vruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-darwin18]$ rails -... $ rails new rails_model_test_hello_world -T -m ~/rtfb_template.rb$ cd rails_model_test_hello_world$ rail
Rails 管理员成为用户 ... rails_admin_become_user必须在rails_admin之后rails_admin才能正常工作。 在您的config/initializers/rails_admin.rb初始化程序中添加配置: RailsAdmin . config do | config |
安装要启用rails_admin_history_rollback ,请将以下内容添加到您的Gemfile确保将其添加到rails_admin之后: gem 'rails_admin'gem 'rails_admin_history_rollback' 不用说,此插件还需要paper_trail gem。...
$ rails new [application_name] -m https://raw.githubusercontent.com/wdi-sf-september-2014/rails_with_rspec_template/master/template.rb -TBd [database] 请参阅 template.rb 了解此模板的作用;)
rails_best_practices的安装和使用都非常方便,只需简单两条命令就能知道代码中何处需要修改: sudo gem install rails_best_practices --source http://gemcutter.org rails_best_practices . 最新的0.3.3版本中...
复杂Rails系统架构优化