Rails проверяет, предотвращает сохранение

#ruby-on-rails #validation

#ruby-on-rails #проверка

Вопрос:

У меня есть пользовательская модель, подобная этой:

 class User < ActiveRecord::Base
    validates :password, :presence => true,
                         :confirmation => true,
                         :length => { :within => 6..40 }
    .
    .
    .
end
  

В пользовательской модели у меня есть столбец billing_id, в который я хочу сохранить из OrdersController, который выглядит следующим образом:

 class OrdersController < ApplicationController
    .
    .
    .
    def create
        @order = Order.new(params[:order])
        if @order.save
            if @order.purchase
                response = GATEWAY.store(credit_card, options)
                result = response.params['billingid']
                @thisuser = User.find(current_user)
                @thisuser.billing_id  = result
                if @thisuser.save
                        redirect_to(root_url), :notice => 'billing id saved')
                    else
                        redirect_to(root_url), :notice => @thisuser.errors)
                    end
            end
        end
    end
  

Из-за validates :password пользовательской модели @thisuser.save не сохраняется. Однако, как только я закомментирую проверку, @thisuser.save возвращает true. Для меня это незнакомая территория, потому что я думал, что эта проверка работает только при создании нового пользователя. Кто-нибудь может мне сказать, validates :password должно ли это срабатывать каждый раз, когда я пытаюсь сохранить в пользовательской модели? Спасибо

Ответ №1:

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

 validates :password,
  :presence => true,
  :confirmation => true,
  :length => { :within => 6..40 },
  :on => :create
  

Альтернативой является запуск этой проверки условно:

 validates :password,
  :presence => true,
  :confirmation => true,
  :length => { :within => 6..40 },
  :if => :password_required?
  

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

 class User < ActiveRecord::Base
  def password_required?
    # Validation required if this is a new record or the password is being
    # updated.
    self.new_record? or self.password?
  end
end
  

Ответ №2:

Вероятно, это связано с тем, что вы проверяете, что пароль был подтвержден ( :confirmation => true ), но password_confirmation не существует.

Вы можете разбить это на что-то вроде:

 validates_presence_of :password, :length => { :within => 6..40 }
validates_presence_of :password_confirmation, :if => :password_changed?
  

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

Комментарии:

1. Спасибо, Джесси, это чрезвычайно полезно