2014-09-16 5 views
0


У меня есть небольшой вопрос - как я могу создать много моделей и сохранить его в базу данных Повсеместно одна формы в Rails 3.
Я имею в виду - у меня есть форма который создает коды - которые генерируют случайные - их содержимое, строку. В контроллере:Rails - Создание множества моделей в одной форме - в контроллере

@code = Code.new(params[:code]) 
characters = [('a'..'z'), ('0'..'9'), ('A'..'Z')].map { |i| i.to_a }.flatten 
@code.code_value = @code.code_letters + (0...8).map { characters[rand(characters.length)] }.join 


Теперь я хочу, чтобы создать коды много раз щелкнув один раз, к примеру, у меня есть input: code_quantity, :integer то я выбираю количество до 1000, а затем, когда я нажимаю submit, в контроллере - создать действие должно создать его 1 * code_quantity раз, но он должен создать уникальный каждый подобный код:

1000.times { @code = Code.new(params[:code]) } 

:code_value имеет проверку уникальности.
Как это сделать в действии контроллера, возможно ли это?

+0

Не совсем понятно, что вы пытаетесь достичь здесь. Я имею в виду. У меня есть форма, которая создает коды, которые генерируют случайное - их содержимое, string.' - генерировать случайные что? что такое «их содержание». Что порождает его, форму? Я могу получить общее представление по этому вопросу, но не могу помочь вам, не переписывая вопрос. – BroiSatse

+0

Эта форма создает содержимое модели - 'Код' -' code_value' заполняется контроллером, а не формой, @ code.code_value заполняется путем генерирования случайных 8 символов. В этой форме также находятся другие входы, такие как код 'valid_date', который должен быть одинаковым во всех кодах, только каждый раз, когда код-код заполняется контроллером, должен быть уникальным. – Neologis

+0

Хорошо, спасибо, гораздо яснее. Однако в вашем вопросе вы добавили некоторый erb, предполагающий, что code_value является частью кода. Измените свой вопрос, чтобы было ясно, что оно не в форме. – BroiSatse

ответ

0

Во-первых, проблемы - создание случайного кода uniq не похоже на то, что должен контролировать контроллер. Это строго связаны модель поведения, поэтому давайте реорганизовать его немного и переместить его в модель:

class Code < ActiveRecord::Base 
    CODE_CHARS = ['a'..'z', '0'..'9', 'A'..'Z'].flat_map &:to_a 

    after_initialize do 
    generate_code unless code_value.present? 
    end 

    def self.generate_code 
    code_letters + (0..8).map { CODE_CHARS.sample }.join 
    end 

    def generate_code 
    self.code_value = self.class.generate_code 
    end 

end 

Теперь было бы заманчиво сделать следующее в контроллере:

@codes = Array.new(params[:code_quantity]) { Code.new(params[:code]) } 
@codes.each &:save 

Это не так легко, хотя - может случиться, что некоторые из ваших моделей нарушат валидность уникальности и не будут сохранены в результате (весьма маловероятно, но есть только 218340105584896 уникальных комбинаций для 8 символов). Чтобы исправить, что вам нужно:

1) Добавить ограничение уникальности в базе данных, если вы еще не (проверка уникальности не обеспечивает уникальность записи - параллелизм является ...):

# New migration 
def change 
    add_index :codes, :code_value, unique: true 
end 

2) Override save! метода:

class Code 
    ... 
    def save!(*args) 
    tries = 0; 
    begin 
     super 
    rescue 
     tries += 1 
     raise if errors.any? || tries > 10 
     generate_code 
     retry 
    end 
    end 

Теперь каждый раз, когда вы пытаетесь сохранить запись и потерпит неудачу по любой другой причине, чем проверки, он будет пытаться регенерировать код 10 раз, прежде чем отказаться.

+1

Большое вам спасибо! Одна строка нуждается в малой правильности: '@codes = Array.new (params [: code_quantity]) {Code.new (params [: code])}' to '@codes = Array.new (params [: code] [: code_quantity ] .to_i) {Код.новый (PARAMS [Код])} '' – Neologis

+0

использования after_initialize на:: создать do' – mohameddiaa27

+0

Еще одна альтернативы для генерации коды: 'Защитой generate_code' ' self.code_value = цикла do' 'random_token = SecureRandom.urlsafe_base64 (ноля , false) ' ' break random_token, если Code.exists? (code_value: random_token) ' ' end' 'end' – mohameddiaa27

Смежные вопросы