Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 4473

Show
Ignore:
Timestamp:
06/20/06 22:48:52 (3 years ago)
Author:
sam
Message:

Added find_or_initialize_by_X which works like find_or_create_by_X but doesn't save the newly instantiated record

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/CHANGELOG

    r4463 r4473  
    11*SVN* 
     2 
     3* Added find_or_initialize_by_X which works like find_or_create_by_X but doesn't save the newly instantiated record. [Sam Stephenson] 
    24 
    35* Row locking. Provide a locking clause with the :lock finder option or true for the default "FOR UPDATE". Use the #lock! method to obtain a row lock on a single record (reloads the record with :lock => true). [Shugo Maeda] 
  • trunk/activerecord/lib/active_record/base.rb

    r4462 r4473  
    180180  #   Tag.find_or_create_by_name("Summer") # equal to Tag.find_by_name("Summer") 
    181181  # 
     182  # Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without saving it first. Example: 
     183  # 
     184  #   # No 'Winter' tag exists 
     185  #   winter = Tag.find_or_initialize_by_name("Winter") 
     186  #   winter.new_record? # true 
     187  # 
    182188  # == Saving arrays, hashes, and other non-mappable objects in text columns 
    183189  # 
     
    11601166                send(deprecated_finder, conditions, *arguments[attribute_names.length..-1]) # deprecated API 
    11611167            end 
    1162           elsif match = /find_or_create_by_([_a-zA-Z]\w*)/.match(method_id.to_s) 
     1168          elsif match = /find_or_(initialize|create)_by_([_a-zA-Z]\w*)/.match(method_id.to_s) 
     1169            instantiator = determine_instantiator(match) 
    11631170            attribute_names = extract_attribute_names_from_match(match) 
    11641171            super unless all_attributes_exists?(attribute_names) 
     
    11661173            options = { :conditions => construct_conditions_from_arguments(attribute_names, arguments) } 
    11671174            set_readonly_option!(options) 
    1168             find_initial(options) || create(construct_attributes_from_arguments(attribute_names, arguments)) 
     1175            find_initial(options) || send(instantiator, construct_attributes_from_arguments(attribute_names, arguments)) 
    11691176          else 
    11701177            super 
     
    11781185        def determine_deprecated_finder(match) 
    11791186          match.captures.first == 'all_by' ? :find_all : :find_first 
     1187        end 
     1188 
     1189        def determine_instantiator(match) 
     1190          match.captures.first == 'initialize' ? :new : :create 
    11801191        end 
    11811192 
  • trunk/activerecord/test/finder_test.rb

    r4425 r4473  
    337337    assert_equal number_of_companies + 1, Company.count 
    338338    assert_equal sig38, Company.find_or_create_by_name("38signals") 
     339    assert !sig38.new_record? 
    339340  end 
    340341 
     
    344345    assert_equal number_of_topics + 1, Topic.count 
    345346    assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John") 
     347    assert !another.new_record? 
     348  end 
     349   
     350  def test_find_or_initialize_from_one_attribute 
     351    sig38 = Company.find_or_initialize_by_name("38signals") 
     352    assert_equal "38signals", sig38.name 
     353    assert sig38.new_record? 
     354  end 
     355   
     356  def test_find_or_initialize_from_two_attributes 
     357    another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John") 
     358    assert_equal "Another topic", another.title 
     359    assert_equal "John", another.author_name 
     360    assert another.new_record? 
    346361  end 
    347362