Error de lanzamiento dinámico define_method en RSpec

Estoy bastante seguro de que me estoy perdiendo un error básico aquí, por lo que espero que otro par de ojos pueda ayudar. Estoy usando Rails 3, Ruby 1.9.2 y Rspec 2.

Me gustaría definir métodos de clase dinámica en un modelo para poder devolver roles base para un objeto asignable (como una cuenta) a medida que se agregan al sistema. Por ejemplo:

BaseRole.creator_for_account

Todo funciona bien a través de la consola:

ruby-1.9.2-p180 :003 > BaseRole.respond_to?(:creator_for_account)
 => true 

pero cuando ejecuto mis especificaciones para cualquiera de los métodos de clase, obtengo un NoMethodError dondequiera que llame al método en la especificación. Supongo que algo acerca de cómo estoy declarando dinámicamente los métodos no es compatible con RSpec, pero parece que no puedo entender por qué.

El directorio lib es una ruta autocargada y los métodos devuelven verdadero para respond_to ?.

# /lib/assignable_base_role.rb
module AssignableBaseRole
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    BaseRole.all.each do |base_role|
      role_type = RoleType.find(base_role.role_type_id)
      assignable_name = base_role.assignable_type.downcase
      method = "#{role_type.name}_for_#{assignable_name}"

      define_method(method) do
        self.where(:role_type_id => role_type.id,
                :assignable_type => assignable_name).first
      end
    end 
  end
end

Luego incluye el Módulo en BaseRole

# /models/base_role.rb
class BaseRole < ActiveRecord::Base
  include AssignableBaseRole

  belongs_to :role
  belongs_to :role_type

  ......
  ......

end

Entonces en mi especificación:

  it "adds correct authority for creator role" do
    create_assignment 
    base_role = BaseRole.creator_for_account # <== NoMethodError here
    user1 = Factory.create(:user)
    account.users << user1
    user1.roles_for_assignable(account).should include(base_role.role)
  end

preguntado el 16 de mayo de 11 a las 17:05

Si quita el módulo, ¿sigue siendo un problema? También obtengo esto con define_method en un archivo de clase, solo con rspec dentro de la guardia. -

2 Respuestas

¿Tenía otra clase en su proyecto o especificaciones con el mismo nombre, pero no tiene los métodos dinámicos agregados? Tuve exactamente el mismo problema que tú, y cambiar el nombre de una de las clases lo solucionó.

Supongo que la otra clase se carga primero

contestado el 08 de mayo de 12 a las 12:05

Parece que está definiendo estos métodos en función de los valores de la base de datos:

BaseRole.all.each do |base_role|
.....

¿Podría ser que "creador" no existe en la base de datos de prueba como un tipo de función, o que "cuenta" no existe como tipo_asignable?

Es de suponer que está probando esto en la consola para el desarrollo, no para probar, por lo que los datos podrían no coincidir. Es posible que deba configurar los datos en un enlace anterior.

contestado el 17 de mayo de 11 a las 00:05

Gracias por la respuesta, verifiqué que los datos de prueba están presentes. Estoy cargando los datos a través de la base de datos y estoy usando la consola en desarrollo, principalmente para ver si definiría los métodos, dada la rareza en RSpec. Pero es posible que esté en algo con el libro anterior y / o precargando los datos de alguna manera. Podría ser algo diferente en cómo se carga todo y / o cuando estoy jugando con la consola frente al entorno de prueba. - Bami Gaffald

Frio. interesado en escuchar lo que averigua. - twmills

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.