验证来自其他模型

时间:2017-03-10 16:33:10

标签: ruby-on-rails validation

具有以下关联:

class Profile < ActiveRecord::Base
  belongs_to :visitor
  belongs_to :contact_point
  validates :contact_point, presence: true
end

class Visitor < User
  has_one :profile, dependent: :destroy
  has_one :contact_point, through: :profile
end

class ContactPoint < User
  has_many :profiles
  has_many :visitors, through: :profiles
end

每个ContactPoint都有一封电子邮件。当访问者使用以下表单创建她的个人资料时,她需要使用属于ContactPoint的电子邮件地址确定个人资料联系人点。已创建联系人用户,访问者无法更新ContactPoint模型。

<%= form_for @profile do |f| %>
  <%= f.label 'First Name' %>
  <%= f.text_field :first_name %>
  <%= f.label 'Last Name' %>
  <%= f.text_field :last_name %>
  <%= fields_for :contact_point, @profile.contact_point do |ff| %>
    <%= ff.label 'Contact point email' %>
    <%= ff.text_field :email %>
  <% end %>
<% end %>

ProfilesController中,我以这种方式将参数传递给配置文件模型:

def create
  @profile = Profile.create(profile_params)
end

def profile_params
  contact_point = ContactPoint.find_by_email(params[:contact_point][:email])
  params.require(:profile).permit(:first_name, :last_name)
                          .merge(visitor_id: current_user.id, contact_point: contact_point)
end

通过上述设置,如果ContactPoint没有提供的电子邮件地址,则contact_point变量将设置为nil,验证者无法区分填写的联络点电子邮件是否为空。 现在,如何添加验证以检查contact_points表中是否存在此电子邮件地址并显示自定义错误消息?

2 个答案:

答案 0 :(得分:0)

最好是使用自定义验证来检查contact_pounts.email是否为空?如果是,则返回false。

编辑:

我的大脑在睡眠后现在运作得更好了。你可以使用rails来做到这一点。我就是这样做的。

class Profile < ActiveRecord::Base
  belongs_to :visitor
  belongs_to :contact_point
  validates :contact_point, presence: true
  accepts_nested_attributes_for :contact_point
end

class Visitor < User
  has_one :profile, dependent: :destroy
  has_one :contact_point, through: :profile
end

class ContactPoint < User
  has_many :profiles
  has_many :visitors, through: :profiles
  validates :email, presence: true
end

这里发生了什么?我们接受来自Profile的关联(ContactPoint)的嵌套属性,因此我们可以通过您对控制器的@profile表单传递它们。模型将处理验证并相应地设置错误消息。

这有意义吗?

答案 1 :(得分:0)

您必须自己在控制器中执行此操作,例如:

def create
  @profile = Profile.create(profile_params)
  if !@profile.contact_point 
    if params[:contact_point][:email].present?
     @profile.errors.add(:contact_point, 'No contact with found')
    else
     @profile.errors.add(:contact_point, 'Please provide an email')
    end
    render :new
  end

end