Как мне заполнить стол в рельсах от прибора? - PullRequest
1 голос
/ 11 мая 2009

Краткое резюме: У меня есть приложение Rails, которое представляет собой личный контрольный список / список дел. Вы можете войти в свой список дел и управлять им.

Мой вопрос: Когда пользователь создает новую учетную запись, я хочу заполнить его контрольный список 20-30 заданиями по умолчанию. Я знаю, что могу сказать:

wash_the_car = ChecklistItem.new
wash_the_car.name = 'Wash and wax the Ford F650.'
wash_the_car.user = @new_user
wash_the_car.save!

...repeat 20 times...

Тем не менее, у меня есть 20 строк ChecklistItem для заполнения, так что это будет 60 строк очень влажного (иначе не СУХОГО) кода. Должен быть лучший способ.

Поэтому я хочу использовать начальную таблицу ChecklistItems из файла YAML при создании учетной записи. Файл YAML может содержать все мои объекты ChecklistItem для заполнения. Когда создается новый пользователь - bam! - предустановленные задачи находятся в их списке.

Как мне это сделать?

Спасибо!

(PS: Для тех из вас, кто интересуется, ПОЧЕМУ я делаю это: я делаю логин клиента для моей компании, занимающейся веб-дизайном. У меня есть набор из 20 шагов (первая встреча, разработка, проверка, тестирование и т. Д.) Я перехожу к каждому веб-клиенту. Эти 20 шагов - это 20 пунктов контрольного списка, которые я хочу заполнить для каждого нового клиента. Однако, хотя все начинают с одних и тех же 20 элементов, я обычно настраиваю шаги, которые предприму в зависимости от проекта. (и, следовательно, моя реализация списка текущих задач и желание заполнять строки программно.) Если у вас есть вопросы, я могу объяснить дальше.

Ответы [ 3 ]

3 голосов
/ 11 мая 2009

Просто напишите функцию:

def add_data(data, user)
wash_the_car = ChecklistItem.new
wash_the_car.name = data
wash_the_car.user = user
wash_the_car.save!
end

add_data('Wash and wax the Ford F650.', @user)
1 голос
/ 12 мая 2009

Я согласен с другими ответчиками, предлагающими сделать это в коде. Но это не должно быть настолько многословно, как предложено. Это уже один лайнер, если вы хотите, чтобы это было:

@new_user.checklist_items.create! :name => 'Wash and wax the Ford F650.'

Добавьте в цикл элементы, которые вы читаете из файла, или храните в своем классе, или где-либо:

class ChecklistItem < AR::Base
  DEFAULTS = ['do one thing', 'do another']
  ...
end

class User < AR::Base
  after_create :create_default_checklist_items

  protected
  def create_default_checklist_items
    ChecklistItem::DEFAULTS.each do |x|
      @new_user.checklist_items.create! :name => x
    end
  end
end

или если ваши элементы усложняются, замените массив строк на массив хэшей ...

# ChecklistItem...
DEFAULTS = [
  { :name => 'do one thing', :other_thing => 'asdf' },
  { :name => 'do another', :other_thing => 'jkl' },
]

# User.rb in after_create hook:    
ChecklistItem::DEFAULTS.each do |x|
  @new_user.checklist_items.create! x
end

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

class ChecklistItem < AR::Base
  def self.defaults
    @@defaults ||= YAML.read ...
  end
end

Или, если вы хотите, чтобы администраторы могли управлять параметрами по умолчанию на лету, поместите их в базу данных:

class ChecklistItem < AR::Base
  named_scope :defaults, :conditions => { :is_default => true }
end

# User.rb in after_create hook:    
ChecklistItem.defaults.each do |x|
  @new_user.checklist_items.create! :name => x.name
end

Много опций.

1 голос
/ 11 мая 2009

Rails Fixture используется для заполнения тестовых данных для юнит-тестов; Не думайте, что это должно быть использовано в упомянутом вами сценарии.

Я бы сказал, просто извлеките новый метод add_checklist_item и покончите с этим.

def on_user_create
  add_checklist_item 'Wash and wax the Ford F650.', @user
  # 19 more invocations to go
end

Если вы хотите больше гибкости

def on_user_create( new_user_template_filename )
  #read each line from file and call add_checklist_item
end

Файл может быть простым текстовым файлом, в котором каждая строка соответствует описанию задачи, например «Вымойте и вытрите Ford F650». Должно быть довольно легко писать на Ruby,

...