Skip to content

Commit

Permalink
Added mongoid support
Browse files Browse the repository at this point in the history
  • Loading branch information
Caio Torres committed Nov 19, 2012
1 parent 706172b commit 757faed
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 36 deletions.
3 changes: 2 additions & 1 deletion Rakefile
Expand Up @@ -5,7 +5,8 @@ desc 'Default: run rspec tests.'
task :default => [:travis]

task :travis do
puts "Starting to run `rspec spec`..."
cmd = "rspec spec"
puts "Starting to run `#{cmd}`..."
system("export DISPLAY=:99.0 && bundle exec rspec spec -c")
raise "#{cmd} failed!" unless $?.exitstatus == 0
end
93 changes: 77 additions & 16 deletions lib/active_repository/base.rb
Expand Up @@ -11,8 +11,6 @@ class Base < ActiveHash::Base
include ActiveModel::Validations::Callbacks
include ActiveRepository::Associations

# TODO: implement first, last,

class_attribute :model_class, :save_in_memory

before_validation :set_timestamps
Expand Down Expand Up @@ -40,7 +38,11 @@ def self.define_custom_find_by_field(field_name)
if self == get_model_class
object = self.where(field_name.to_sym => args.first).first
else
object = get_model_class.send(method_name, args)
if mongoid?
object = get_model_class.where(field_name.to_sym => args.first).first
else
object = get_model_class.send(method_name, args)
end
end

object.nil? ? nil : serialize!(object.attributes)
Expand All @@ -57,7 +59,12 @@ def self.define_custom_find_all_by_field(field_name)
if self == get_model_class
objects = self.where(field_name.to_sym => args.first)
else
objects = get_model_class.send(method_name, args)
objects = []
if mongoid?
objects = get_model_class.where(field_name.to_sym => args.first)
else
objects = get_model_class.send(method_name, args)
end
end

objects.empty? ? [] : objects.map{ |object| serialize!(object.attributes) }
Expand All @@ -70,7 +77,13 @@ def self.find(id)
if self == get_model_class
super(id)
else
object = get_model_class.find(id)
object = nil

if id == :all
object = all
else
object = get_model_class.find(id)
end

if object.is_a?(Array)
object.map { |o| serialize!(o.attributes) }
Expand Down Expand Up @@ -99,15 +112,23 @@ def self.exists?(id)
if self == get_model_class
!find_by_id(id).nil?
else
get_model_class.exists?(id)
if mongoid?
find_by_id(id).present?
else
get_model_class.exists?(id)
end
end
end

def self.find_by_id(id)
if self == get_model_class
super(id)
else
get_model_class.find_by_id(id)
if mongoid?
get_model_class.where(:id => id).entries.first
else
get_model_class.find_by_id(id)
end
end
end

Expand All @@ -122,23 +143,49 @@ def self.find_or_create(attributes)
def self.create(attributes={})
object = get_model_class.new(attributes)

object.id = nil if get_model_class.exists?(object.id)
object.id = nil if exists?(object.id)

object.save
if get_model_class == self
object.save
else
repository = serialize!(object.attributes)
repository.valid? ? (object = get_model_class.create(attributes)) : false
end

serialize!(object.attributes) unless object.class.name == self
end

def update_attributes(attributes)
object = self.class.get_model_class.find(self.id)
object = nil
if mongoid?
object = self.class.get_model_class.find(self.id)
else
object = self.class.get_model_class.find(self.id)
end

attributes.each do |k,v|
object.send("#{k.to_s}=", v) unless k == :id
object.update_attribute("#{k.to_s}", v) unless k == :id
end

object.save
self.reload
end

def update_attribute(key, value)
if self.class == self.class.get_model_class
super(key,value)
else
object = self.class.get_model_class.find(self.id)

if mongoid?
super(key,value)
key = key.to_s == 'id' ? '_id' : key.to_s
end

object.update_attribute(key, value)
object.save
end

self.attributes = object.attributes
self.reload
end

def self.all
Expand Down Expand Up @@ -203,7 +250,13 @@ def self.get(position)
end

def convert(attribute="id")
object = self.class.get_model_class.send("find_by_#{attribute}", self.send(attribute))
object = nil

if mongoid?
object = self.class.where(attribute.to_sym => self.send(attribute)).first
else
object = self.class.get_model_class.send("find_by_#{attribute}", self.send(attribute))
end

object = self.class.get_model_class.new if object.nil?

Expand All @@ -220,14 +273,14 @@ def convert(attribute="id")

def attributes=(new_attributes)
new_attributes.each do |k,v|
self.send("#{k.to_s}=", v)
self.send("#{k.to_s == '_id' ? 'id' : k.to_s}=", v)
end
end

def serialize!(attributes)
unless attributes.nil?
attributes.each do |k,v|
self.send("#{k.to_s}=", v)
self.send("#{k.to_s == '_id' ? 'id' : k.to_s}=", v)
end
end

Expand Down Expand Up @@ -262,5 +315,13 @@ def set_timestamps
self.created_at = DateTime.now.utc if self.new_record?
self.updated_at = DateTime.now.utc
end

def self.mongoid?
get_model_class.included_modules.include?(Mongoid::Document)
end

def mongoid?
self.class.mongoid?
end
end
end
11 changes: 10 additions & 1 deletion lib/active_repository/write_support.rb
Expand Up @@ -51,6 +51,11 @@ def self.validate_unique_id(record)
raise IdError.new("Duplicate Id found for record #{record.attributes}") if record_index.has_key?(record.id.to_s)
end

def update_attribute(key, value)
self.send("#{key}=", value)
self.save(:validate => false)
end

def readonly?
false
end
Expand All @@ -62,9 +67,13 @@ def save(*args)
true
end

def to_param
id.present? ? id.to_s : nil
end

def persisted?
other = self.class.find_by_id(id)
other.present? && other.created_at
other.present?
end

def eql?(other)
Expand Down
70 changes: 68 additions & 2 deletions spec/active_repository/base_spec.rb
Expand Up @@ -2,8 +2,8 @@
require 'support/shared_examples'

require 'active_repository'
require "active_record"
require "mongoid"
require 'active_record'
require 'mongoid'

describe ActiveRepository, "Base" do

Expand Down Expand Up @@ -120,4 +120,70 @@ class CountryModel < ActiveRecord::Base
it_behaves_like '.transaction'
it_behaves_like '.delete_all'
end

context "mongoid" do
before do
Country.fields :name, :monarch, :language

Mongoid.load!("support/mongoid.yml", :development)

class CountryModel
include Mongoid::Document

store_in collection: "countries"

field :name
field :monarch
field :language
field :_id, type: Integer, default: -> { CountryModel.last ? CountryModel.last.id + 1 : 1 }
field :updated_at
field :created_at
end

Country.set_model_class(CountryModel)
Country.set_save_in_memory(false)

Country.delete_all

Country.create(:id => 1, :name => "US", :language => 'English')
Country.create(:id => 2, :name => "Canada", :language => 'English', :monarch => "The Crown of England")
Country.create(:id => 3, :name => "Mexico", :language => 'Spanish')
Country.create(:id => 4, :name => "UK", :language => 'English', :monarch => "The Crown of England")
Country.create(:id => 5, :name => "Brazil")
end

after do
Object.send :remove_const, :CountryModel
end

it_behaves_like '.update_attributes'
it_behaves_like '.all'
it_behaves_like '.where'
it_behaves_like '.exists?'
it_behaves_like '.count'
it_behaves_like '.first'
it_behaves_like '.last'
it_behaves_like '.find'
it_behaves_like '.find_by_id'
it_behaves_like 'custom finders'
it_behaves_like '#method_missing'
it_behaves_like '#attributes'
it_behaves_like 'reader_methods'
it_behaves_like 'interrogator methods'
it_behaves_like '#id'
it_behaves_like '#quoted_id'
it_behaves_like '#to_param'
it_behaves_like '#persisted?'
it_behaves_like '#eql?'
it_behaves_like '#=='
it_behaves_like '#hash'
it_behaves_like '#readonly?'
it_behaves_like '#cache_key'
it_behaves_like '#save'
it_behaves_like '.create'
it_behaves_like '#valid?'
it_behaves_like '#new_record?'
it_behaves_like '.transaction'
it_behaves_like '.delete_all'
end
end
1 change: 0 additions & 1 deletion spec/active_repository/sql_query_executor_spec.rb
Expand Up @@ -3,7 +3,6 @@

require 'active_repository'
require "active_record"
require "mongoid"

describe ActiveRepository, "Base" do

Expand Down
39 changes: 24 additions & 15 deletions spec/support/shared_examples.rb
Expand Up @@ -30,10 +30,9 @@

it "populates the data correctly" do
records = Country.all
records.first.id.should == 1
records.first.name.should == "US"
records.last.id.should == 5
records.last.name.should == "Brazil"
records.should include(Country.first)
records.should include(Country.last)
records.size.should == 5
end
end

Expand Down Expand Up @@ -72,12 +71,13 @@

shared_examples ".exists?" do
it "checks if a record exists" do
id = Country.last.id + 1
id = Country.last.id

Country.delete_all
Country.exists?(id).should be_false

country = Country.create(:id => id, :name => "France")
country = Country.create(:name => "France")
id = country.id

Country.exists?(id).should be_true
end
Expand Down Expand Up @@ -120,7 +120,11 @@

context "with :all" do
it "returns all records" do
Country.find(:all).should == [Country.find(1), Country.find(2), Country.find(3), Country.find(4), Country.find(5)]
records = Country.find(:all)

records.should include(Country.first)
records.should include(Country.last)
records.size.should == 5
end
end

Expand Down Expand Up @@ -446,9 +450,13 @@ class Region < ActiveRepository::Base
end

it 'should use the record\'s updated_at if present' do
country = Country.create(:id => 6, :name => "foo")
country = Country.create(:name => "foo")

Country.first.cache_key.should == "countries/6-#{country.updated_at.to_s(:number)}"
id = Country.last.id

date_string = country.updated_at.nil? ? "" : "-#{country.updated_at.to_s(:number)}"

Country.first.cache_key.should == "countries/#{id}#{date_string}"
end

it 'should use "new" instead of the id for a new record' do
Expand Down Expand Up @@ -479,14 +487,15 @@ class Region < ActiveRepository::Base

it "works with no args" do
Country.all.should be_empty
country = Country.create :id => 6
country.id.should == 6
country = Country.create

country.id.should == Country.last.id
end

it "adds the new object to the data collection" do
Country.all.should be_empty
country = Country.create :id => 6, :name => "foo"
country.id.should == 6
country = Country.create :name => "foo"
country.id.should == Country.last.id
country.name.should == "foo"
Country.all.should == [country]
end
Expand All @@ -509,8 +518,8 @@ class Region < ActiveRepository::Base

it "adds the new object to the data collection" do
Country.all.should be_empty
country = Country.create :id => 6, :name => "foo"
country.id.should == 6
country = Country.create :name => "foo"
country.id.should == Country.last.id
country.name.should == "foo"

Country.all.should == [country]
Expand Down

0 comments on commit 757faed

Please sign in to comment.