Ruby on rails Rails-在一个form-in控制器中创建多个模型

Ruby on rails Rails-在一个form-in控制器中创建多个模型,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我有一个小问题——如何创建多个模型并通过Rails 3中的一个表单将其保存到数据库中。 我的意思是,我有一个表单,它可以创建代码,生成随机的内容,字符串。 在控制器中: @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 { ch

我有一个小问题——如何创建多个模型并通过Rails 3中的一个表单将其保存到数据库中。 我的意思是,我有一个表单,它可以创建代码,生成随机的内容,字符串。 在控制器中:

@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
@codes = Array.new(params[:code_quantity]) { Code.new(params[:code]) }
@codes.each &:save
现在我想多次创建代码单击一次,例如,我有一个输入:code\u quantity,:integer,然后我选择quantity to 1000,然后当我单击submit时,在controller-create action中,应该创建1*code\u quantity次,但应该创建唯一的每个代码,如:

:code_值具有唯一性验证。
如何在控制器动作中做到这一点,可能吗?

首先,关注点-生成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
但这并不是那么容易-可能会发生一些模型会破坏唯一性验证,因此不太可能保存,但对于8个字符,只有218340105584896个唯一组合。要解决此问题,您需要:

1如果还没有唯一性验证,请向数据库添加唯一性约束。唯一性验证不能确保记录的唯一性-并发性是…:

# New migration
def change
  add_index :codes, :code_value, unique: true
end
2覆盖保存!方法:


现在,每次您尝试保存记录时,它都会因为验证以外的任何其他原因而失败,在放弃之前,它会尝试重新生成代码10次

现在还不太清楚你想在这里实现什么,我的意思是-我有一个表单,它可以创建代码-生成随机的-它们的内容,字符串。-随机生成什么?他们的内容是什么。是什么产生的,形式?我可以理解这个问题背后的大致意思,但我可以;如果不重新编写问题,则无法为您提供帮助。此表单创建一个模型-代码-代码值内容由controller填写,而不是在@Code.Code\u表单中,通过生成随机8个字符来填写。此表单中还有其他输入,如所有代码中应相同的代码有效日期,只有控制器填写的代码值每次都应唯一。好的,谢谢,现在更清楚了。然而,在您的问题中,您提出了一些erb建议,code_值是代码的一部分。请编辑您的问题,使其明确不在表单中。已编辑-感谢您的关注并等待答复!多谢各位!一行需要小的更正:@codes=Array.newparams[:code\u quantity]{code.newparams[:code]}到@codes=Array.newparams[:code][:code\u quantity]。到{code.newparams[:code]}在初始化之后使用::创建另一种代码生成方法:def generate\u code self.code\u value=loop do random\u token=SecureRandom.urlsafe\u base64nil,错误中断随机\u令牌,除非存在代码?代码\u值:随机\u令牌结束end@mohameddiaa27-请注意,这仍然需要唯一约束和保存覆盖,因为它不能保证代码的唯一性。
# New migration
def change
  add_index :codes, :code_value, unique: true
end
class Code 
  ...
  def save!(*args)
    tries = 0;
    begin
      super
    rescue
      tries += 1
      raise if errors.any? || tries > 10
      generate_code
      retry
    end
  end