From d18ff1b7efd96e7c08bc1a15137735be45f87e07 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 7 Apr 2010 13:04:52 -0700 Subject: new helpers #favicon_link_tag and #apple_touch_icon_link_tag --- .../lib/action_view/helpers/asset_tag_helper.rb | 38 ++++++++++++++++++++++ actionpack/test/template/asset_tag_helper_test.rb | 19 +++++++++++ 2 files changed, 57 insertions(+) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index e4ec17467e..1ca95b7dd1 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -501,6 +501,44 @@ module ActionView end end + # Returns a link tag for a favicon. + # + # <%= favicon_link_tag %> + # + # generates + # + # + # + # You can specify a different icon file in the first argument: + # + # <%= favicon_link_tag 'favicon.ico' %> + # + # That's passed to +image_path+ as is, so the example above would render + # + # + # + # The helper accepts an additional options hash where you can override "rel" and "type". + def favicon_link_tag(source=nil, options={}) + tag('link', { + :rel => 'shortcut icon', + :type => 'image/vnd.microsoft.icon', + :href => image_path(source || '/favicon.ico') + }.merge(options.symbolize_keys)) + end + + # Returns a link tag for an icon targetted at iPod Touch, iPhone, and iPad. + # + # <%= apple_touch_icon_link_tag 'my_site.png' %> + # + # generates + # + # + # + # The source argument is passed to +image_path+ as is. + def apple_touch_icon_link_tag(source) + tag('link', :rel => 'apple-touch-icon', :href => image_path(source)) + end + # Computes the path to an image asset in the public images directory. # Full paths from the document root will be passed through. # Used internally by +image_tag+ to build the image path. diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 223a430f92..71052fb22c 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -157,6 +157,17 @@ class AssetTagHelperTest < ActionView::TestCase %(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %(Mouse) } + FaviconLinkToTag = { + %(favicon_link_tag) => %(), + %(favicon_link_tag 'favicon.ico') => %(), + %(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(), + %(favicon_link_tag 'favicon.ico', :rel => 'foo', :type => 'bar') => %() + } + + AppleTouchIconLinkToTag = { + %(apple_touch_icon_link_tag 'my_site.png') => %() + } + VideoPathToTag = { %(video_path("xml")) => %(/videos/xml), %(video_path("xml.ogg")) => %(/videos/xml.ogg), @@ -331,6 +342,14 @@ class AssetTagHelperTest < ActionView::TestCase ImageLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end + def test_favicon_link_tag + FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + + def test_apple_touch_link_tag + AppleTouchIconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + def test_image_tag_windows_behaviour old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1" # This simulates the behaviour of File#exist? on windows when testing a file ending in "." -- cgit v1.2.3 From eed89e65b6320a59115da0c5ef004c727e0f9cbf Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 7 Apr 2010 15:07:40 -0500 Subject: Make sure MemCacheStore logger exists --- activesupport/lib/active_support/cache/mem_cache_store.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index d84a62ca2d..c56fedc12e 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -64,7 +64,7 @@ module ActiveSupport @data.get(key, raw?(options)) end rescue MemCache::MemCacheError => e - logger.error("MemCacheError (#{e}): #{e.message}") + logger.error("MemCacheError (#{e}): #{e.message}") if logger nil end @@ -85,7 +85,7 @@ module ActiveSupport response == Response::STORED end rescue MemCache::MemCacheError => e - logger.error("MemCacheError (#{e}): #{e.message}") + logger.error("MemCacheError (#{e}): #{e.message}") if logger false end @@ -95,7 +95,7 @@ module ActiveSupport response == Response::DELETED end rescue MemCache::MemCacheError => e - logger.error("MemCacheError (#{e}): #{e.message}") + logger.error("MemCacheError (#{e}): #{e.message}") if logger false end -- cgit v1.2.3 From ec8610cfdc32d0fe816fb22405e00ef1b6c90d73 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 7 Apr 2010 13:19:55 -0700 Subject: adds a default source to #apple_touch_icon_link_tag --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 18 ++++++++++++------ actionpack/test/template/asset_tag_helper_test.rb | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 1ca95b7dd1..47abf1e41c 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -518,24 +518,30 @@ module ActionView # # # The helper accepts an additional options hash where you can override "rel" and "type". - def favicon_link_tag(source=nil, options={}) + def favicon_link_tag(source='/favicon.ico', options={}) tag('link', { :rel => 'shortcut icon', :type => 'image/vnd.microsoft.icon', - :href => image_path(source || '/favicon.ico') + :href => image_path(source) }.merge(options.symbolize_keys)) end # Returns a link tag for an icon targetted at iPod Touch, iPhone, and iPad. # - # <%= apple_touch_icon_link_tag 'my_site.png' %> + # <%= apple_touch_icon_link_tag %> # # generates # - # + # + # + # You can specify a different icon file: + # + # <%= apple_touch_icon_link_tag "my_site.png" %> # - # The source argument is passed to +image_path+ as is. - def apple_touch_icon_link_tag(source) + # That's passed to +image_path+ as is, so the example above would render + # + # + def apple_touch_icon_link_tag(source='/apple-touch-icon.png') tag('link', :rel => 'apple-touch-icon', :href => image_path(source)) end diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 71052fb22c..10ee9c7881 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -165,6 +165,7 @@ class AssetTagHelperTest < ActionView::TestCase } AppleTouchIconLinkToTag = { + %(apple_touch_icon_link_tag) => %(), %(apple_touch_icon_link_tag 'my_site.png') => %() } -- cgit v1.2.3 From 6891f46d10957f21f200fc4dc2b6076ff411b1da Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 7 Apr 2010 15:07:07 -0700 Subject: adds #favicon_link_tag and #apple_touch_icon_link_tag to AP's CHANGELOG --- actionpack/CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 84481d0194..3c765933ef 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.0.0 [Edge] (pending)* +* New helpers #favicon_link_tag and #apple_touch_icon_link_tag [fxn] + * Added all the new HTML5 form types as individual form tag methods (search, url, number, etc) #3646 [Stephen Celis] * Changed the object used in routing constraints to be an instance of -- cgit v1.2.3 From 336cb3c0bf3d38400f6c774ca78376117b899985 Mon Sep 17 00:00:00 2001 From: Mikel Lindsaar Date: Thu, 8 Apr 2010 15:52:35 +1000 Subject: Adding Rails.env= to railties to allow changing of rails env on the fly for rake tasks etc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- railties/lib/rails.rb | 4 ++++ railties/test/railties/railtie_test.rb | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 9d02da104d..085b82c154 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -79,6 +79,10 @@ module Rails @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development") end + def env=(environment) + @_env = ActiveSupport::StringInquirer.new(environment) + end + def cache RAILS_CACHE end diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb index 546bf5e143..2accaca855 100644 --- a/railties/test/railties/railtie_test.rb +++ b/railties/test/railties/railtie_test.rb @@ -125,5 +125,16 @@ module RailtiesTest require "#{app_path}/config/environment" assert $ran_block end + + test "we can change our environment if we want to" do + begin + original_env = Rails.env + Rails.env = 'foo' + assert_equal('foo', Rails.env) + ensure + Rails.env = original_env + assert_equal(original_env, Rails.env) + end + end end end -- cgit v1.2.3 From 4e92134dfa15ae198c714b85376838ffec5a7773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 8 Apr 2010 12:52:37 +0200 Subject: Fix a bug in ActionDispatch::Static where Rails cannot find assets if started in another directory which is not the RAILS_ROOT. --- actionpack/lib/action_controller/caching/pages.rb | 4 ++-- actionpack/lib/action_controller/metal/compatibility.rb | 2 -- actionpack/lib/action_controller/railtie.rb | 6 ++++++ railties/lib/rails.rb | 5 +++-- railties/lib/rails/application/configuration.rb | 2 +- railties/test/application/configuration_test.rb | 9 +++++++++ 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index fe95f0e0d7..2a0a1107eb 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -38,22 +38,22 @@ module ActionController #:nodoc: extend ActiveSupport::Concern included do - @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" ## # :singleton-method: # The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root". # For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public"). Changing # this setting can be useful to avoid naming conflicts with files in public/, but doing so will likely require configuring your # web server to look in the new location for cached files. + @@page_cache_directory = '' cattr_accessor :page_cache_directory - @@page_cache_extension = '.html' ## # :singleton-method: # Most Rails requests do not have an extension, such as /weblog/new. In these cases, the page caching mechanism will add one in # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is .html. # If you want something else, like .php or .shtml, just set Base.page_cache_extension. In cases where a request already has an # extension, such as .xml or .rss, page caching will not add an extension. This allows it to work well with RESTful apps. + @@page_cache_extension = '.html' cattr_accessor :page_cache_extension end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index e6cea483bb..02722360f1 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -32,8 +32,6 @@ module ActionController def rescue_action(env) raise env["action_dispatch.rescue.exception"] end - - self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" end # For old tests diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 030ba4ec48..b029434004 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -44,6 +44,12 @@ module ActionController ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger } end + initializer "action_controller.page_cache_directory" do + ActiveSupport.on_load(:action_controller) do + self.page_cache_directory = Rails.public_path + end + end + initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 085b82c154..0611b2a9f5 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -92,11 +92,12 @@ module Rails end def public_path - @@public_path ||= self.root ? File.join(self.root, "public") : "public" + application && application.paths.public.to_a.first end def public_path=(path) - @@public_path = path + ActiveSupport::Deprecation.warn "Setting Rails.public_path= is deprecated. " << + "Please set paths.public = in config/application.rb instead.", caller end end end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index f9f47ef679..7ce3494fa6 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -137,7 +137,7 @@ module Rails def default_middleware_stack ActionDispatch::MiddlewareStack.new.tap do |middleware| - middleware.use('::ActionDispatch::Static', lambda { Rails.public_path }, :if => lambda { serve_static_assets }) + middleware.use('::ActionDispatch::Static', lambda { paths.public.to_a.first }, :if => lambda { serve_static_assets }) middleware.use('::Rack::Lock', :if => lambda { !allow_concurrency }) middleware.use('::Rack::Runtime') middleware.use('::Rails::Rack::Logger') diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 97d5f64708..8bf0f09d6b 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -184,6 +184,15 @@ module ApplicationTests end end + test "config.paths.public sets Rails.public_path" do + add_to_config <<-RUBY + config.paths.public = "somewhere" + RUBY + + require "#{app_path}/config/application" + assert_equal File.join(app_path, "somewhere"), Rails.public_path + end + def make_basic_app require "rails" require "action_controller/railtie" -- cgit v1.2.3 From 91d1012a98975979473709adf723a94057bda295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 8 Apr 2010 13:53:18 +0200 Subject: Update rails.js to the latest one at http://github.com/rails/prototype-ujs --- .../app/templates/public/javascripts/rails.js | 73 ++++++++++++---------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js index 7342e1b830..c5fa02ae35 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js @@ -1,15 +1,8 @@ document.observe("dom:loaded", function() { - var authToken = $$('meta[name=csrf-token]').first().readAttribute('content'), - authParam = $$('meta[name=csrf-param]').first().readAttribute('content'), - formTemplate = '
\ - #{realmethod}\ -
', - realmethodTemplate = ''; - function handleRemote(element) { var method, url, params; - if (element.tagName.toLowerCase() == 'form') { + if (element.tagName.toLowerCase() === 'form') { method = element.readAttribute('method') || 'post'; url = element.readAttribute('action'); params = element.serialize(true); @@ -39,65 +32,81 @@ document.observe("dom:loaded", function() { element.fire("ajax:after"); } + function handleMethod(element) { + var method, url, token_name, token; + + method = element.readAttribute('data-method'); + url = element.readAttribute('href'); + csrf_param = $$('meta[name=csrf-param]').first(); + csrf_token = $$('meta[name=csrf-token]').first(); + + var form = new Element('form', { method: "POST", action: url, style: "display: none;" }); + element.parentNode.appendChild(form); + + if (method != 'post') { + var field = new Element('input', { type: 'hidden', name: '_method', value: method }); + form.appendChild(field); + } + + if (csrf_param) { + var param = csrf_param.readAttribute('content'); + var token = csrf_token.readAttribute('content'); + var field = new Element('input', { type: 'hidden', name: param, value: token }); + form.appendChild(field); + } + + form.submit(); + } + $(document.body).observe("click", function(event) { - var message = event.element().readAttribute('data-confirm'); + var message = event.findElement().readAttribute('data-confirm'); if (message && !confirm(message)) { event.stop(); return false; } - var element = event.findElement("a[data-remote=true]"); + var element = event.findElement("a[data-remote]"); if (element) { handleRemote(element); event.stop(); + return true; } var element = event.findElement("a[data-method]"); - if (element && element.readAttribute('data-remote') != 'true') { - var method = element.readAttribute('data-method'), - piggyback = method.toLowerCase() != 'post', - formHTML = formTemplate.interpolate({ - method: 'POST', - realmethod: piggyback ? realmethodTemplate.interpolate({ method: method }) : '', - action: element.readAttribute('href'), - token: authToken, - param: authParam - }); - - var form = new Element('div').update(formHTML).down().hide(); - this.insert({ bottom: form }); - - form.submit(); + if (element) { + handleMethod(element); event.stop(); + return true; } }); // TODO: I don't think submit bubbles in IE $(document.body).observe("submit", function(event) { - var message = event.element().readAttribute('data-confirm'); + var element = event.findElement(), + message = element.readAttribute('data-confirm'); if (message && !confirm(message)) { event.stop(); return false; } - var inputs = event.element().select("input[type=submit][data-disable-with]"); + var inputs = element.select("input[type=submit][data-disable-with]"); inputs.each(function(input) { input.disabled = true; input.writeAttribute('data-original-value', input.value); input.value = input.readAttribute('data-disable-with'); }); - var element = event.findElement("form[data-remote=true]"); + var element = event.findElement("form[data-remote]"); if (element) { handleRemote(element); event.stop(); } }); - $(document.body).observe("ajax:complete", function(event) { - var element = event.element(); + $(document.body).observe("ajax:after", function(event) { + var element = event.findElement(); - if (element.tagName.toLowerCase() == 'form') { + if (element.tagName.toLowerCase() === 'form') { var inputs = element.select("input[type=submit][disabled=true][data-disable-with]"); inputs.each(function(input) { input.value = input.readAttribute('data-original-value'); @@ -106,4 +115,4 @@ document.observe("dom:loaded", function() { }); } }); -}); +}); \ No newline at end of file -- cgit v1.2.3 From 2c27e3d336df0600581c01b794d90cd09efd6b09 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 8 Apr 2010 16:49:38 +0100 Subject: Some doc updates reflecting the new query API --- .../associations/association_collection.rb | 2 +- activerecord/lib/active_record/base.rb | 68 ++++++++++------------ 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index c1ec98a9c6..b808f8c306 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -147,7 +147,7 @@ module ActiveRecord # has_many :books # end # - # Author.find(:first).books.transaction do + # Author.first.books.transaction do # # same effect as calling Book.transaction # end def transaction(*args) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index f0b107255c..2df1024a1b 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -56,15 +56,15 @@ module ActiveRecord #:nodoc: # # class User < ActiveRecord::Base # def self.authenticate_unsafely(user_name, password) - # find(:first, :conditions => "user_name = '#{user_name}' AND password = '#{password}'") + # where("user_name = '#{user_name}' AND password = '#{password}'").first # end # # def self.authenticate_safely(user_name, password) - # find(:first, :conditions => [ "user_name = ? AND password = ?", user_name, password ]) + # where("user_name = ? AND password = ?", user_name, password).first # end # # def self.authenticate_safely_simply(user_name, password) - # find(:first, :conditions => { :user_name => user_name, :password => password }) + # where(:user_name => user_name, :password => password).first # end # end # @@ -77,30 +77,30 @@ module ActiveRecord #:nodoc: # question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing # the question marks with symbols and supplying a hash with values for the matching symbol keys: # - # Company.find(:first, :conditions => [ + # Company.where( # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date", # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' } - # ]) + # ).first # # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND # operator. For instance: # - # Student.find(:all, :conditions => { :first_name => "Harvey", :status => 1 }) - # Student.find(:all, :conditions => params[:student]) + # Student.where(:first_name => "Harvey", :status => 1) + # Student.where(params[:student]) # # A range may be used in the hash to use the SQL BETWEEN operator: # - # Student.find(:all, :conditions => { :grade => 9..12 }) + # Student.where(:grade => 9..12) # # An array may be used in the hash to use the SQL IN operator: # - # Student.find(:all, :conditions => { :grade => [9,11,12] }) + # Student.where(:grade => [9,11,12]) # # When joining tables, nested hashes or keys written in the form 'table_name.column_name' can be used to qualify the table name of a # particular condition. For instance: # - # Student.find(:all, :conditions => { :schools => { :type => 'public' }}, :joins => :schools) - # Student.find(:all, :conditions => { 'schools.type' => 'public' }, :joins => :schools) + # Student.joins(:schools).where(:schools => { :type => 'public' }) + # Student.joins(:schools).where('schools.type' => 'public' ) # # == Overwriting default accessors # @@ -153,18 +153,18 @@ module ActiveRecord #:nodoc: # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects by simple queries without turning to SQL. They work by # appending the name of an attribute to find_by_, find_last_by_, or find_all_by_, so you get finders like Person.find_by_user_name, # Person.find_all_by_last_name, and Payment.find_by_transaction_id. So instead of writing - # Person.find(:first, :conditions => ["user_name = ?", user_name]), you just do Person.find_by_user_name(user_name). - # And instead of writing Person.find(:all, :conditions => ["last_name = ?", last_name]), you just do Person.find_all_by_last_name(last_name). + # Person.where(:user_name => user_name).first, you just do Person.find_by_user_name(user_name). + # And instead of writing Person.where(:last_name => last_name).all, you just do Person.find_all_by_last_name(last_name). # # It's also possible to use multiple attributes in the same find by separating them with "_and_", so you get finders like # Person.find_by_user_name_and_password or even Payment.find_by_purchaser_and_state_and_country. So instead of writing - # Person.find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password]), you just do + # Person.where(:user_name => user_name, :password => password).first, you just do # Person.find_by_user_name_and_password(user_name, password). # - # It's even possible to use all the additional parameters to find. For example, the full interface for Payment.find_all_by_amount - # is actually Payment.find_all_by_amount(amount, options). And the full interface to Person.find_by_user_name is - # actually Person.find_by_user_name(user_name, options). So you could call Payment.find_all_by_amount(50, :order => "created_on"). - # Also you may call Payment.find_last_by_amount(amount, options) returning the last record matching that amount and options. + # It's even possible to call these dynamic finder methods on relations and named scopes. For example : + # + # Payment.order("created_on").find_all_by_amount(50) + # Payment.pending.find_last_by_amount(100) # # The same dynamic finder style can be used to create the object if it doesn't already exist. This dynamic finder is called with # find_or_create_by_ and will return the object if it already exists and otherwise creates it, then returns it. Protected attributes won't be set unless they are given in a block. For example: @@ -224,7 +224,7 @@ module ActiveRecord #:nodoc: # class PriorityClient < Client; end # # When you do Firm.create(:name => "37signals"), this record will be saved in the companies table with type = "Firm". You can then - # fetch this row again using Company.find(:first, "name = '37signals'") and it will return a Firm object. + # fetch this row again using Company.where(:name => '37signals').first and it will return a Firm object. # # If you don't have a type column defined in your table, single-table inheritance won't be triggered. In that case, it'll work just # like normal subclasses with no special magic for differentiating between them or reloading the right type with find. @@ -1117,10 +1117,6 @@ module ActiveRecord #:nodoc: # It's even possible to use all the additional parameters to +find+. For example, the full interface for +find_all_by_amount+ # is actually find_all_by_amount(amount, options). # - # Also enables dynamic scopes like scoped_by_user_name(user_name) and scoped_by_user_name_and_password(user_name, password) that - # are turned into scoped(:conditions => ["user_name = ?", user_name]) and scoped(:conditions => ["user_name = ? AND password = ?", user_name, password]) - # respectively. - # # Each dynamic finder, scope or initializer/creator is also defined in the class after it is first invoked, so that future # attempts to use it do not run through method_missing. def method_missing(method_id, *arguments, &block) @@ -1196,12 +1192,12 @@ module ActiveRecord #:nodoc: protected # Scope parameters to method calls within the block. Takes a hash of method_name => parameters hash. - # method_name may be :find or :create. :find parameters may include the :conditions, :joins, - # :include, :offset, :limit, and :readonly options. :create parameters are an attributes hash. + # method_name may be :find or :create. :find parameter is Relation while + # :create parameters are an attributes hash. # # class Article < ActiveRecord::Base # def self.create_with_scope - # with_scope(:find => { :conditions => "blog_id = 1" }, :create => { :blog_id => 1 }) do + # with_scope(:find => where(:blog_id => 1), :create => { :blog_id => 1 }) do # find(1) # => SELECT * from articles WHERE blog_id = 1 AND id = 1 # a = create(1) # a.blog_id # => 1 @@ -1210,20 +1206,20 @@ module ActiveRecord #:nodoc: # end # # In nested scopings, all previous parameters are overwritten by the innermost rule, with the exception of - # :conditions, :include, and :joins options in :find, which are merged. + # where, includes, and joins operations in Relation, which are merged. # - # :joins options are uniqued so multiple scopes can join in the same table without table aliasing + # joins operations are uniqued so multiple scopes can join in the same table without table aliasing # problems. If you need to join multiple tables, but still want one of the tables to be uniqued, use the # array of strings format for your joins. # # 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 }) do - # find(:all) # => SELECT * from articles WHERE blog_id = 1 LIMIT 10 + # with_scope(:find => where(:blog_id => 1).limit(1), :create => { :blog_id => 1 }) do + # with_scope(:find => limit(10)) do + # all # => SELECT * from articles WHERE blog_id = 1 LIMIT 10 # end - # with_scope(:find => { :conditions => "author_id = 3" }) do - # find(:all) # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1 + # with_scope(:find => where(:author_id => 3)) do + # all # => SELECT * from articles WHERE blog_id = 1 AND author_id = 3 LIMIT 1 # end # end # end @@ -1233,9 +1229,9 @@ module ActiveRecord #:nodoc: # # class Article < ActiveRecord::Base # def self.find_with_exclusive_scope - # with_scope(:find => { :conditions => "blog_id = 1", :limit => 1 }) do - # with_exclusive_scope(:find => { :limit => 10 }) - # find(:all) # => SELECT * from articles LIMIT 10 + # with_scope(:find => where(:blog_id => 1).limit(1)) do + # with_exclusive_scope(:find => limit(10)) + # all # => SELECT * from articles LIMIT 10 # end # end # end -- cgit v1.2.3