Есть ли find_or_create_by_, который принимает хэш в Rails? - PullRequest
9 голосов
/ 01 октября 2010

Вот мой производственный код (мне пришлось форсировать разрывы строк):

task = Task.find_or_create_by_username_and_timestamp_and_des \
cription_and_driver_spec_and_driver_spec_origin(username,tim \
estamp,description,driver_spec,driver_spec_origin)

Да, я пытаюсь найти или создать уникальный ActiveRecord::Base объект.Но в нынешнем виде это очень некрасиво.Вместо этого я хотел бы использовать что-то вроде этого:

task = Task.SOME_METHOD :username => username, :timestamp => timestamp ...

Я знаю о find_by_something key=>value, но это не вариант здесь.Мне нужно, чтобы все ценности были уникальными.Есть ли метод, который будет делать то же самое, что и find_or_create_by, но принимать хеш в качестве входных данных?Или что-то еще с семантикой similat?

Ответы [ 2 ]

19 голосов
/ 01 октября 2010

Rails 3.2 впервые представил first_or_create в ActiveRecord. Он не только имеет запрошенную функциональность, но также вписывается в остальные отношения ActiveRecord:

Task.where(attributes).first_or_create

В Rails 3.0 и 3.1:

Task.where(attributes).first || Task.create(attributes)

В Rails 2.1 - 2.3:

Task.first(:conditions => attributes) || Task.create(attributes)

В более старых версиях вы всегда можете написать метод с именем find_or_create, чтобы инкапсулировать это, если хотите Определенно сделал это сам в прошлом:

class Task
  def self.find_or_create(attributes)
    # add one of the implementations above
  end
end
4 голосов
/ 06 марта 2012

Я также расширяю метод @ wuputah для получения массива хэшей, что очень полезно при использовании внутри db/seeds.rb

class ActiveRecord::Base
  def self.find_or_create(attributes)
    if attributes.is_a?(Array)
      attributes.each do |attr|
        self.find_or_create(attr)
      end
    else
      self.first(:conditions => attributes) || self.create(attributes)
    end
  end
end


# Example
Country.find_or_create({:name => 'Aland Islands', :iso_code => 'AX'})

# take array of hashes
Country.find_or_create([
  {:name => 'Aland Islands', :iso_code => 'AX'},
  {:name => 'Albania', :iso_code => 'AL'},
  {:name => 'Algeria', :iso_code => 'DZ'}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...