FactoryGirl trouble - ruby

I have a class that is defined in the module.
module Mod
class Zed
include DataMapper::Resource
end
end
For testing, I define factory.
#/factories/zed.rb
FactoryGirl.define do
factory :zed do
#code
end
end
But when I start testing I get an error.
describe 'Zed' do
it "should have ..." do
FactoryGirl.create(:zed)
end
end
Error:
Failure/Error: FactoryGirl.create(:zed)
NameError:
uninitialized constant Zed
How to test a class that is included in the module?
Thanks.

You should specify class when defining a factory like this:
FactoryGirl.define do
factory :zed, class: Mod::Zed do
#code
end
end

Related

NameError: uninitialized constant when referring to class within module

I have the following tests, written using RSpec
spec/services/aquatic/factory_spec.rb
describe Hobby::Aquatic::Factory do
let(:factory) { Hobby::Aquatic::Factory.instance }
describe "singleton" do
it "should be the same object" do
Hobby::Aquatic::Factory.instance.should be factory
end
it "raise error if given junk" do
expect {factory.hobby("junk")}.to raise_error
end
end
end
spec/services/aquatic/hobbies_spec.rb
describe Hobby::Aquatic do
it "creates fishing" do
expect { Hobby::Aquatic::Fishing.new }.to_not raise_error
end
end
and have defined the following module / classes
app/services/aquatic/factory.rb
require 'singleton'
module Hobby
module Aquatic
class Factory
include Singleton
def self.instance
##instance ||= new
end
def hobby(name)
return Fishing.new if name == "fishing"
return Surfing.new if name == "surfing"
raise ArgumentError, "Unknown hobby for supplied name"
end
end
end
end
app/services/aquatic/hobbies.rb
module Hobby
module Aquatic
class Fishing
end
class Surfing
end
end
end
When I run the tests the Factory tests all pass fine, but the test of the Hobby::Aquatic::Fishing object results in:
Failure/Error: expect { Hobby::Aquatic::Fishing.new }.to_not raise_error
expected no Exception, got #<NameError: uninitialized constant Hobby::Aquatic::Fishing> …
What have I done wrong?
add require_relative 'hobbies' below require 'singleton' to fix this.
I am not sure why Rails is loading the factory but not the hobbies automagically but this works.

Call parent method in child class

I'm learning the object model of Ruby. I've written this script:
#/usr/bin/ruby
module MyModule
class MyBase
def class_b_method
puts "class_b_method called"
end
end
class MyClass < MyBase
attr_accessor :name
class_b_method
def set_name(name)
#name = "My name is #{name}"
end
def display_name
return #name
end
end
end
obj = MyModule::MyClass.new
obj.set_name "Martin"
puts obj.display_name
Running the code above I get this error:
module.rb:13: undefined local variable or method `class_b_method' for MyModule::MyClass:Class (NameError)
I'm trying to call the parent method within the class MyClass. What I'm doing wrong?
Inside class MyClass,self is MyClass.But you define class_b_method as an instance method inside class MyBase,i.e. method which can be called by the instances of the class MyBase,can't be invoked by the class itself. so self.class_b_method throws an legitimate error.To make your code workable write the method as below:
class MyBase
def self.class_b_method
puts "class_b_method called"
end
end

Defining attr_accessor for class instance variables - Ruby

I am trying to create an accessor for a class instance variable. I am calling the attr_accessor method from a module which is included in the class. See the code below:
module Persistence
def self.included(mod)
mod.extend ClassMethods
# Add accessor for class instance variable
class << mod
attr_accessor :persistent_data
end
end
module ClassMethods
def X
persistent_data = 'data'
end
end
end
The above code works. However when I change the code which calls attr_accessor, to this:
mod.instance_eval do
attr_accessor :persistent_data
end
I get NoMethodError: undefined method `persistent_data='
Shouldn't both ways work the same or is my understanding wrong here? I am using REE 1.8.7

Why 'self' method of module cannot become a singleton method of class?

module Test
def self.model_method
puts "this is a module method"
end
end
class A
include Test
end
A.model_method
this will be error with:
undefined method `model_method' for A:Class (NoMethodError)
But when I use metaclass of A. it works:
module Test
def model_method
puts "this is a module method"
end
end
class A
class << self
include Test
end
end
A.model_method
Can someone explain this?
If you want to have both class methods and instance methods mixed into a class when including a module, you may follow the pattern:
module YourModule
module ClassMethods
def a_class_method
puts "I'm a class method"
end
end
def an_instance_method
puts "I'm an instance method"
end
def self.included(base)
base.extend ClassMethods
end
end
class Whatever
include YourModule
end
Whatever.a_class_method
# => I'm a class method
Whatever.new.an_instance_method
# => I'm an instance method
Basically to over-simplify it, you extend to add class methods and you include to add instance methods. When a module is included, it's #included method is invoked, with the actual class it was included in. From here you can extend the class with some class methods from another module. This is quite a common pattern.
See also: http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
Including a module is analogous to copying its instance methods over.
In your example, there are no instance methods to copy to A. model_method is actually an instance method of Test's singleton class.
Given:
module A
def method
end
end
This:
module B
include A
end
Is analogous to this:
module B
def method
end
end
When you think of it this way, this makes perfect sense:
module B
class << self
include A
end
end
B.method
Here, the methods are being copied to the B module's singleton class, which makes them the "class methods" of B.
Note that this is exactly the same thing as:
module B
extend A
end
In reality, the methods are not being copied; there is no duplication. The module is simply included in the method lookup list.

What's the purpose of singleton_class.send & singleton_class.class_eval in this metaprogramming example?

class Product < ActiveRecord::Base
set_table_name 'produce'
end
module ActiveRecord
class Base
def self.set_table_name name
define_attr_method :table_name, name
end
def self.define_attr_method(name, value)
singleton_class.send :alias_method, "original_#{name}", name
singleton_class.class_eval do
define_method(name) do
value
end
end
end
end
I'd like to understand how set_table_name becomes defined in this example.
Why is singleton_class.send needed here?
And why is class_eval called on singleton_class instead of on self?
The reason for using "singleton_class" is because you do not want to modify the ActiveRecord::Base class, but the Product class.
More info about metaptogramming and singleton class here: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

Resources