Модель Rails 4 rspec для условия if

Я новичок в Rails, и я пытаюсь посмотреть в свой объект, чтобы увидеть, истинно ли значение, чтобы проверить все остальные элементы в объекте. У меня, конечно, есть, если человек является пользователем, подтвердите имя и адрес электронной почты в приложении/модели. Как лучше написать спецификацию для этого?

class Members < ActiveRecord::Base
    validates_presence_of :email, if: :is_user?
    validates_presence_of :first_name, if: :is_user?
    validates_presence_of :last_name, if: :is_user?

    def is_user?
        :is_user
    end
end

person Katherine Bangert    schedule 09.12.2014    source источник
comment
is_user — это поле в базе данных.   -  person Katherine Bangert    schedule 09.12.2014


Ответы (2)


У вас есть поле с именем «is_user» в таблице участников? Кажется, что метод должен возвращать логическое значение (истина или ложь), а теперь он возвращает символ, который всегда будет оцениваться как истина, например, если вы это сделаете.

if :is_user
  puts "will always happen" # this will be printed
end

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

Теперь, чтобы проверить, что вы можете использовать гем, такой как shoulda_matchers, или вы можете написать свой собственные тесты, такие как

describe "validations" do
  context "member is a user" do
    subject { Member.new(is_user: true) }

    it "validates presence of email" do
      subject.valid?
      expect(subject.errors["email"]).to include("can't be blank")
    end
  end

  context "member is not an user" do
    subject { Member.new(is_user: false) }

    it "doesn't require fields to have info" do
      subject.valid?
      expect(subject.errors["email"]).to_not include("can't be blank")
      expect(subject.errors["first_name"]).to_not include("can't be blank")
      expect(subject.errors["last_name"]).to_not include("can't be blank")
    end
  end
end
person rafb3    schedule 09.12.2014
comment
Да, это логическое значение. Итак, мне нужно было бы сделать что-то другое для файла модели приложения? или что у меня на данный момент приемлемо? - person Katherine Bangert; 09.12.2014
comment
если это логическое значение, которое у вас есть в поле is_user в базе данных, удалите этот метод, иначе он всегда будет истинным, и эти проверки всегда будут выполняться. Если это то, что вы хотите, вы можете удалить метод и часть if: ... в объявлении проверки. - person rafb3; 09.12.2014
comment
Откуда он знает, если вы явно не говорите, что значение должно быть истинным, чтобы другие поля имели значения? - person Katherine Bangert; 09.12.2014
comment
эй, так что validates_presence_of :email, if: :is_user? говорит, проверяйте, было ли передано электронное письмо, только если участник является пользователем, но метод, который вы определили для is_user?, возвращает символ, а не значение поля в вашей базе данных, а рубиновый объект, который всегда будет оцениваться к истине. Затем эта проверка будет выполняться каждый раз и независимо от значения поля is_user в базе данных, потому что она рассчитывает на результат определенного вами метода is_user?, который всегда является одним и тем же значением, символом, который оценивается как истинный. - person rafb3; 09.12.2014
comment
когда я говорю, что оценивается как true, я имею в виду, что при использовании условия if как if :any_symbol он всегда будет выполнять все, что будет после этого. В отличие от nil или false, которые при использовании в операторе if никогда не будут выполнять условный код. - person rafb3; 09.12.2014
comment
Я получаю сообщение об ошибке не в пользовательской части. Оно возвращается ложным. Должен ли я проверять ложное состояние? - person Katherine Bangert; 09.12.2014
comment
проверьте ошибки на subject.errors.messages, это карта полей для массивов сообщений об ошибках, там должно быть указано, какие ошибки есть у этого экземпляра, которые делают его не valid?. Может оказаться, что у вас больше проверок, чем те, которые вы представили здесь, и тогда вам следует проверить, присутствуют ли интересующие вас поля (email, first_name, last_name) в ошибках. Я обновляю ответ, чтобы дать вам представление - person rafb3; 09.12.2014
comment
Потрясающий. Спасибо за вашу помощь и терпение. - person Katherine Bangert; 09.12.2014

Вы должны использовать сопоставители shouda, это было бы сортировано и красиво:
Пример взят отсюда Shoulda/ Сопоставители RSpec — условная проверка

context "if user" do
  before { subject.stub(:is_user?) { true } }
  it { should validate_presence_of(:name) }
  it { should validate_presence_of(:email) }
end

context "if not user" do
  before { subject.stub(:is_user?) { false } }
  it { should_not validate_presence_of(:name) }
  it { should validate_presence_of(:email) }
end
person Ashutosh Tiwari    schedule 09.12.2014