Ruby on rails Rails-新用户生成依赖的电子邮件并验证这两种邮件?

Ruby on rails Rails-新用户生成依赖的电子邮件并验证这两种邮件?,ruby-on-rails,validation,associations,Ruby On Rails,Validation,Associations,我正在构建一个QuickRails项目,允许用户管理他们的电子邮件地址。用户可以有许多电子邮件,但其中一封(而且只有一封)必须标记为“主要”(用于登录),并且没有主要电子邮件的用户无法生存 我一直在努力让它正常工作——它对我来说似乎是如此循环。我需要构建一个用户,然后是电子邮件,但我不想将用户保存到数据库中,除非电子邮件有效,而在保存用户之前,电子邮件是无效的(因为validates:User,presence:true约束) 接受的嵌套资源似乎不适用于.new(适用于.create),如果我的

我正在构建一个QuickRails项目,允许用户管理他们的电子邮件地址。用户可以有许多电子邮件,但其中一封(而且只有一封)必须标记为“主要”(用于登录),并且没有主要电子邮件的用户无法生存

我一直在努力让它正常工作——它对我来说似乎是如此循环。我需要构建一个用户,然后是电子邮件,但我不想将用户保存到数据库中,除非电子邮件有效,而在保存用户之前,电子邮件是无效的(因为
validates:User,presence:true
约束)

接受的嵌套资源似乎不适用于
.new
(适用于
.create
),如果我的电子邮件验证失败,用户仍显示为有效

为了从一个表单中构建/验证多个/相关模型,我们一直在努力寻找好的资源(或者一些问题)

最有效的方法是什么

使用者 电子邮件 用户控制器 编辑 电子邮件模型还包含以下字段:

  • 标签=字符串,如“个人”、“工作”等
  • primary=布尔值,无论是否标记为主电子邮件
  • 确认\代码=创建时自动生成,用于确认所有权
  • 已确认=布尔值,无论是否已确认
因此,在用户初始化其构建后,将生成一封主电子邮件,以便记录已经关联,或者如果可以保存,至少会关联。autosave的工作非常酷——如果主电子邮件由于验证错误而无法保存,那么用户也无法保存。应该是开箱即用的,我现在在公共汽车上,不能检查。干杯

进一步资料:


如果任何关联的验证失败,它们的错误消息将应用于父模型。这意味着父模型(在您的案例中是用户)有错误,这就是无法保存的原因!这就是你要找的

我会将主电子邮件存储为公共字段,并以其他方式存储其他电子邮件。我更愿意将额外的电子邮件存储在另一个字段(即数组)中,而不是存储在关联的表中。您不应该将主电子邮件存储在另一个表中。想象一下,每当您需要授权用户或只是收到他的电子邮件时,您都会向db执行一个额外的请求

本打算在几个月前发布

解决方案是使用的反向,在不同模型之间保持用户和电子邮件的规范化,而不将主电子邮件存储为用户的属性:

User.rb
class用户
Email.rb
class电子邮件
这允许使用内存中的对象而不是通过数据库调用执行验证(即验证对象关联,而不是验证数据库中是否存在id/记录)。因此,它们都通过了验证,并且都可以保存在同一事务中


请参阅:

对于您收到的答案,您的反馈如何?抱歉-我直到现在才能够回到计算机上。我最初的想法是,将主电子邮件存储在用户上,并将其他电子邮件存储在其他位置,这将导致更复杂的过程,以切换哪个电子邮件是主电子邮件-该字段在用户上更新,现在的主电子邮件的原始电子邮件记录被删除,并且为以前的主电子邮件创建了一个新的电子邮件模型,而不是仅仅更改主布尔字段。另一个想法是我有其他数据要跟踪电子邮件-我只是更新了问题以反映这些字段。考虑到其他信息,唯一的两个选项似乎是(1)独立的模型,就像我正在做的,或者(2)一系列的商店。我是否错过了一个选择?HStore阵列是更好的方法吗?谢谢!我以前没有见过Autosave协会。。我现在就试着解决这个问题。文档行,
当:autosave选项不存在时,则会保存新的关联记录,但不会保存更新的关联记录。
让我觉得它已经在尝试自动保存新的关联记录,但我也会尝试这样做,感谢链接到电子邮件验证器gem!我遇到了与昨天相同的问题-新用户生成新的主电子邮件,但我无法保存用户,因为关联的电子邮件对象没有链接到该对象的用户,这会使用户的状态约束失效。如果我执行
new_user.primary_email.user=new_user
new_user.save
,它会起作用,因为电子邮件会检查用户的存在,而不是用户id(还不存在),但这似乎很糟糕。我是否应该删除电子邮件模型中的
验证:用户,存在:true
?我认为我们应该始终进行状态验证,以防止坏数据潜在地进入数据库。这要视情况而定。实际上,在用户模型中,我会给用户一封电子邮件(主要),只是有些人有很多其他的电子邮件。这是最简单、最稳定的方法
has_many :emails
has_one :primary_email, -> { where(primary: true) }, class_name: "Email"

accepts_nested_attributes_for :primary_email

validates :first_name, presence: true
validates :last_name, presence: true
validates :birthday, presence: true
validates :password_digest, presence: true
belongs_to :user

validates :user, presence: true
validates :address, presence: true, uniqueness: {
  case_sensitive: false
}
def new
  @user = User.new
end

def create
  @user = User.new(user_params)
  if @user.save
    # do something
  else
    # show @user.errors
  end
end

private

def user_params
  params.require(:user).permit(
    :first_name,
    :last_name,
    :birthday,
    :password,
    :password_confirmation,
    :primary_email_attributes => [:address]
  )
end
class User
  user has_many :emails
  user has_one :primary_email, -> { where(primary: true) }, class_name: "Email", autosave: true

  after_initialize {
     build_primary_email if new_record?
  }
end


class Email
    # use gem https://github.com/balexand/email_validator
    validates :my_email_attribute, :email => true
end
class User < ActiveRecord::Base
  has_many :emails, inverse_of: :user, dependent: :destroy
  accepts_nested_attributes_for :emails
  validates :emails, presence: true
end
class Email < ActiveRecord::Base
  belongs_to :user, inverse_of: :emails
  validates :user, presence: true
end