简体   繁体   English

设置Rails验证。 在一种形式中使用两个模型

[英]Setting Rails Validations. Using two models in one form

I have a Group model and a Message model, each are HABTM. 我有一个Group模型和一个Message模型,每个模型都是HABTM。 I'm trying to set a validation for my main form which is to send out a SMS to certain groups. 我正在尝试为我的主表单设置验证,即向某些组发送短信。 Right now I have the body of message validated with presence: true , that is working fine but in my Group model I want to validate name to be present but how to I have them both validate when I'm calling a create method in the messages controller? 现在我有使用presence: true验证的消息正文presence: true ,这工作正常,但在我的Group模型中我想验证名称是否存在但是当我在消息中调用create方法时如何让它们都验证控制器? I'll show my code for more clarification. 我将展示我的代码以获得更多说明。

Here is group.rb 这是group.rb

  class Group < ActiveRecord::Base
   has_and_belongs_to_many :people
   has_and_belongs_to_many :messages
   validates :name, presence: true 
  end

Now message.rb 现在是message.rb

class Message < ActiveRecord::Base
  has_and_belongs_to_many :groups

  validates :body, presence: true
end

Here is my message_controller.rb 这是我的message_controller.rb

def create
@message = Message.create(message_params)
if @message.save
  run_at_time = @message.send_at.present? ? @message.send_at : Time.zone.now
  people = Person.in_groups(message_params[:group_ids])
  if people.any?
    people.each do |person|
      person.delay(run_at: run_at_time).send_message(@message.body)
    end
    flash[:success] = "Messages on their way!"
  end
  redirect_to root_path
else
  render "new"
end
end

在此输入图像描述

For more understanding I want my form to display "Groups can't be blank" as well as "body can't be blank". 为了更好地理解,我希望我的表单显示“组不能为空”以及“正文不能为空”。 If nothing is selected. 如果没有选择任何内容

If you want to validate multiple models before saving or collect all errors, you could do it by using model.valid? 如果要在保存或收集所有错误之前验证多个模型,可以使用model.valid?model.valid? method. 方法。 It will return true of false, depending on whether there are any errors. 它将返回true为false,具体取决于是否存在任何错误。 And errors will be added to model.errors . 并且错误将被添加到model.errors

Using valid? 使用valid? was the first thing that came to mind, but there is another way as well. 这是我想到的第一件事,但也有另一种方式。

Model validations actually have built-in support for assoiations. 模型验证实际上具有对关联的内置支持。

For example, 例如,

class Message
  has_and_belongs_to_many :groups
  validates :groups, presence: true
end

See this StackOverflow answer . 请参阅此StackOverflow答案

So this would cause save to fail if the message had no groups. 因此,如果消息没有组,这将导致save失败。

There's always another way - you can override valid? 总有另一种方式 - 你可以覆盖valid? , which is called internally by save . ,由save内部调用。 For example: 例如:

class Message
  def valid?(*args)
    original_result = super(*args)
    if self.groups.empty?
      self.errors_add(:groups, "cannot be empty")
      return false
    end
    return original_result
  end
end

This is largely the same thing accomplished by validates :groups, presence: true , although I think presence: true will also verify that the foreign keys refer to valid records (rather than just checking that any associated record exist). 这与validates :groups, presence: true完全相同validates :groups, presence: true ,虽然我认为presence: true也将验证外键是否引用有效记录(而不仅仅是检查是否存在任何相关记录)。

Calling valid? 打电话valid? has the side effect of loading up the errors object. 有加载errors对象的副作用。 For example: 例如:

  msg = Message.new
  msg.errors.full_messages # => []
  msg.valid? # => false
  msg.errors.full_messages # => ["Name cant be blank", "Groups cant be blank"]
  msg.save # => false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM