adding initial support for belongs_to associations
This commit is contained in:
parent
64e34ee2e8
commit
a7a6b2f0ac
|
@ -11,9 +11,11 @@
|
||||||
* Fixed issue with active_support in Rails3 and text in README for JSON.
|
* Fixed issue with active_support in Rails3 and text in README for JSON.
|
||||||
* Refactoring of properties, added read_attribute and write_attribute methods.
|
* Refactoring of properties, added read_attribute and write_attribute methods.
|
||||||
* Now possible to send anything to update_attribtues method. Invalid or readonly attributes will be ignored.
|
* Now possible to send anything to update_attribtues method. Invalid or readonly attributes will be ignored.
|
||||||
|
* Attributes with arrays are *always* instantiated as a CastedArray.
|
||||||
|
|
||||||
* Major enhancements
|
* Major enhancements
|
||||||
* Added support for anonymous CastedModels defined in Documents
|
* Added support for anonymous CastedModels defined in Documents
|
||||||
|
* Added initial support for simple belongs_to associations
|
||||||
|
|
||||||
== 1.0.0.beta5
|
== 1.0.0.beta5
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ module CouchRest
|
||||||
include CouchRest::Mixins::Collection
|
include CouchRest::Mixins::Collection
|
||||||
include CouchRest::Mixins::AttributeProtection
|
include CouchRest::Mixins::AttributeProtection
|
||||||
include CouchRest::Mixins::Attributes
|
include CouchRest::Mixins::Attributes
|
||||||
|
include CouchRest::Mixins::Associations
|
||||||
|
|
||||||
# Including validation here does not work due to the way inheritance is handled.
|
# Including validation here does not work due to the way inheritance is handled.
|
||||||
#include CouchRest::Validation
|
#include CouchRest::Validation
|
||||||
|
|
|
@ -10,3 +10,4 @@ require File.join(mixins_dir, 'class_proxy')
|
||||||
require File.join(mixins_dir, 'collection')
|
require File.join(mixins_dir, 'collection')
|
||||||
require File.join(mixins_dir, 'attribute_protection')
|
require File.join(mixins_dir, 'attribute_protection')
|
||||||
require File.join(mixins_dir, 'attributes')
|
require File.join(mixins_dir, 'attributes')
|
||||||
|
require File.join(mixins_dir, 'associations')
|
||||||
|
|
58
lib/couchrest/mixins/associations.rb
Normal file
58
lib/couchrest/mixins/associations.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
module CouchRest
|
||||||
|
module Mixins
|
||||||
|
module Associations
|
||||||
|
|
||||||
|
# Basic support for relationships between ExtendedDocuments
|
||||||
|
|
||||||
|
def self.included(base)
|
||||||
|
base.extend(ClassMethods)
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
|
||||||
|
def belongs_to(attrib, *options)
|
||||||
|
opts = {
|
||||||
|
:foreign_key => attrib.to_s + '_id',
|
||||||
|
:class_name => attrib.to_s.camelcase
|
||||||
|
}
|
||||||
|
case options.first
|
||||||
|
when Hash
|
||||||
|
opts.merge!(options.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
opts[:class] = opts[:class_name].constantize
|
||||||
|
rescue
|
||||||
|
raise "Unable to convert belongs_to class name into Constant for #{self.name}##{attrib}"
|
||||||
|
end
|
||||||
|
|
||||||
|
prop = property(opts[:foreign_key])
|
||||||
|
|
||||||
|
create_belongs_to_getter(attrib, prop, opts)
|
||||||
|
create_belongs_to_setter(attrib, prop, opts)
|
||||||
|
|
||||||
|
prop
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_belongs_to_getter(attrib, property, options)
|
||||||
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
||||||
|
def #{attrib}
|
||||||
|
@#{attrib} ||= #{options[:class_name]}.get(self.#{options[:foreign_key]})
|
||||||
|
end
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_belongs_to_setter(attrib, property, options)
|
||||||
|
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
||||||
|
def #{attrib}=(value)
|
||||||
|
@#{attrib} = value
|
||||||
|
self.#{options[:foreign_key]} = value.nil? ? nil : value.id
|
||||||
|
end
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
79
spec/couchrest/assocations_spec.rb
Normal file
79
spec/couchrest/assocations_spec.rb
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require File.expand_path('../../spec_helper', __FILE__)
|
||||||
|
|
||||||
|
class Client < CouchRest::ExtendedDocument
|
||||||
|
use_database DB
|
||||||
|
|
||||||
|
property :name
|
||||||
|
property :tax_code
|
||||||
|
end
|
||||||
|
|
||||||
|
class SaleInvoice < CouchRest::ExtendedDocument
|
||||||
|
use_database DB
|
||||||
|
|
||||||
|
belongs_to :client
|
||||||
|
belongs_to :alternate_client, :class_name => 'Client', :foreign_key => 'alt_client_id'
|
||||||
|
|
||||||
|
property :date, Date
|
||||||
|
property :price, Integer
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
describe "Assocations" do
|
||||||
|
|
||||||
|
describe "of type belongs to" do
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
@invoice = SaleInvoice.create(:price => "sam", :price => 2000)
|
||||||
|
@client = Client.create(:name => "Sam Lown")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a foreign key property with setter and getter" do
|
||||||
|
@invoice.properties.find{|p| p.name == 'client_id'}.should_not be_nil
|
||||||
|
@invoice.respond_to?(:client_id).should be_true
|
||||||
|
@invoice.respond_to?("client_id=").should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should set the property and provide object when set" do
|
||||||
|
@invoice.client = @client
|
||||||
|
@invoice.client_id.should eql(@client.id)
|
||||||
|
@invoice.client.should eql(@client)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should set the attribute, save and return" do
|
||||||
|
@invoice.client = @client
|
||||||
|
@invoice.save
|
||||||
|
@invoice = SaleInvoice.get(@invoice.id)
|
||||||
|
@invoice.client.id.should eql(@client.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should remove the association if nil is provided" do
|
||||||
|
@invoice.client = @client
|
||||||
|
@invoice.client = nil
|
||||||
|
@invoice.client_id.should be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise error if class name does not exist" do
|
||||||
|
lambda {
|
||||||
|
class TestBadAssoc < CouchRest::ExtendedDocument
|
||||||
|
belongs_to :test_bad_item
|
||||||
|
end
|
||||||
|
}.should raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow override of foreign key" do
|
||||||
|
@invoice.respond_to?(:alternate_client).should be_true
|
||||||
|
@invoice.respond_to?("alternate_client=").should be_true
|
||||||
|
@invoice.properties.find{|p| p.name == 'alt_client_id'}.should_not be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow override of foreign key and save" do
|
||||||
|
@invoice.alternate_client = @client
|
||||||
|
@invoice.save
|
||||||
|
@invoice = SaleInvoice.get(@invoice.id)
|
||||||
|
@invoice.alternate_client.id.should eql(@client.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
4
spec/fixtures/more/invoice.rb
vendored
4
spec/fixtures/more/invoice.rb
vendored
|
@ -4,7 +4,7 @@ class Invoice < CouchRest::ExtendedDocument
|
||||||
|
|
||||||
# Set the default database to use
|
# Set the default database to use
|
||||||
use_database DB
|
use_database DB
|
||||||
|
|
||||||
# Official Schema
|
# Official Schema
|
||||||
property :client_name
|
property :client_name
|
||||||
property :employee_name
|
property :employee_name
|
||||||
|
@ -14,4 +14,4 @@ class Invoice < CouchRest::ExtendedDocument
|
||||||
validates_presence_of :client_name, :employee_name
|
validates_presence_of :client_name, :employee_name
|
||||||
validates_presence_of :location, :message => "Hey stupid!, you forgot the location"
|
validates_presence_of :location, :message => "Hey stupid!, you forgot the location"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue