3 votes

Test RSpec à vérifier (modèle Rails : valide :something, :inclusion => liste à partir d'un autre activeRecord)

Voici le code que j'utilise :

Il s'agit de mon app/models archivo:

class One < ActiveRecord::Base
  attr_accessible :name, :surname      
end

class Two < ActiveRecord::Base  
  attr_accessible :name, :one_surname

  # generate a list of one's surnames
  def self.LIST_SURNAMES
    list  = Array.new
    arr   = One.all
    arr.each {|one| list << one.surname}

    return list
  end

  validates :one_surname, :inclusion => self.LIST_SURNAMES()
end

Il s'agit de mon /spec/models archivo:

FactoryGirl.define do
  factory :two do
    name "two_name"
  end

  factory :one do
    name "one_name"
    surname "one_surname"
  end    
end

describe Two do
  it 'should be created' do
    @one = FactoryGirl.create(:one)

    puts "One.last.surname = #{One.last.surname}"
    puts "Two.LIST_SURNAMES = #{Two.LIST_SURNAMES}"

    @two = FactoryGirl.build(:two, :one_surname => Two.LIST_SURNAMES[0])

    @two.save!
  end
end 

Cependant, mon test échoue. Et je ne sais pas du tout pourquoi. Des idées ?

Il s'agit de la RSpec de la production :

One.last.surname  = one_surname
Two.LIST_SURNAMES = ["one_surname"]

De plus, j'obtiens cet échec :

  1) Two should be created
     Failure/Error: @two.save!
     ActiveRecord::RecordInvalid:
       Validation failed: One surname is not included in the list
 # ./category_spec.rb:29:in `block (2 levels) in <top (required)>'

5voto

Jesse Wolgamott Points 30552

Il exécute Two.LIST_SURNAMES au moment de l'interprétation, et non au moment de l'exécution. Donc, si vous voulez qu'il obtienne LIST_SURNAMES au moment de l'exécution, vous devrez utiliser une proc

validates :one_surname, :inclusion => {:in => proc {self.LIST_SURNAMES()}}

Le reste est facultatif, mais voici un peu de code nettoyé :

class Two < ActiveRecord::Base
  attr_accessible :name, :one_surname

  validates :one_surname, :inclusion => {in: proc{One.pluck(:surname)}}                                              
end

J'ai remplacé le LIST_SURNAMES avec la méthode One.pluck(:surname) qui fait la même chose. Aussi : LIST_SURNAMES, si vous le conservez, devrait être def self.list_surnames puisqu'il ne s'agit pas d'une constante.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X