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

Ticket #7368: dynamic_finders_with_hash_attributes.diff

File dynamic_finders_with_hash_attributes.diff, 3.1 kB (added by hasmanyjosh, 2 years ago)

dynamic finders with hash attributes for creation

  • test/finder_test.rb

    old new  
    385385    assert !another.new_record? 
    386386  end 
    387387   
     388  def test_find_or_create_from_one_attribute_and_hash 
     389    number_of_companies = Company.count 
     390    sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23}) 
     391    assert_equal number_of_companies + 1, Company.count 
     392    assert_equal sig38, Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23}) 
     393    assert !sig38.new_record? 
     394    assert_equal "38signals", sig38.name 
     395    assert_equal 17, sig38.firm_id 
     396    assert_equal 23, sig38.client_of 
     397  end 
     398 
    388399  def test_find_or_initialize_from_one_attribute 
    389400    sig38 = Company.find_or_initialize_by_name("38signals") 
    390401    assert_equal "38signals", sig38.name 
     
    397408    assert_equal "John", another.author_name 
    398409    assert another.new_record? 
    399410  end 
     411   
     412  def test_find_or_initialize_from_one_attribute_and_hash 
     413    sig38 = Company.find_or_initialize_by_name({:name => "38signals", :firm_id => 17, :client_of => 23}) 
     414    assert_equal "38signals", sig38.name 
     415    assert_equal 17, sig38.firm_id 
     416    assert_equal 23, sig38.client_of 
     417    assert sig38.new_record? 
     418  end 
    400419 
    401420  def test_find_with_bad_sql 
    402421    assert_raises(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" } 
  • lib/active_record/base.rb

    old new  
    188188  #   winter = Tag.find_or_initialize_by_name("Winter") 
    189189  #   winter.new_record? # true 
    190190  # 
     191  # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of 
     192  # a list of parameters. For example: 
     193  # 
     194  #   Tag.find_or_create_by_name(:name => "rails", :creator => current_user) 
     195  # 
     196  # That will either find an existing tag named "rails", or create a new one while setting the user that created it. 
     197  # 
    191198  # == Saving arrays, hashes, and other non-mappable objects in text columns 
    192199  # 
    193200  # Active Record can serialize any object in text columns using YAML. To do so, you must specify this with a call to the class method +serialize+. 
     
    12261233            attribute_names = extract_attribute_names_from_match(match) 
    12271234            super unless all_attributes_exists?(attribute_names) 
    12281235 
    1229             attributes = construct_attributes_from_arguments(attribute_names, arguments) 
    1230             options = { :conditions => attributes } 
     1236            if arguments[0].is_a?(Hash) 
     1237              attributes = arguments[0].with_indifferent_access 
     1238              find_attributes = attributes.slice(*attribute_names) 
     1239            else 
     1240              find_attributes = attributes = construct_attributes_from_arguments(attribute_names, arguments) 
     1241            end 
     1242            options = { :conditions => find_attributes } 
    12311243            set_readonly_option!(options) 
    12321244 
    12331245            find_initial(options) || send(instantiator, attributes)