Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sequel adapter #89

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ GEM
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
sequel (3.25.0)
tzinfo (0.3.28)

PLATFORMS
Expand All @@ -45,3 +46,4 @@ DEPENDENCIES
rcov
rdoc
rspec
sequel
10 changes: 5 additions & 5 deletions lib/machinist/lathe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ def make_one_value(attribute, args) #:nodoc:
yield
end

def assign_attribute(key, value) #:nodoc:
@assigned_attributes[key.to_sym] = value
@object.send("#{key}=", value)
def assign_attribute(attribute, value) #:nodoc:
@assigned_attributes[attribute.to_sym] = value
@object.send("#{attribute}=", value)
end

def attribute_assigned?(key) #:nodoc:
@assigned_attributes.has_key?(key.to_sym)
def attribute_assigned?(attribute) #:nodoc:
@assigned_attributes.has_key?(attribute.to_sym)
end

def raise_argument_error(attribute) #:nodoc:
Expand Down
16 changes: 16 additions & 0 deletions lib/machinist/sequel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'sequel'
require 'machinist'
require 'machinist/sequel/blueprint'
require 'machinist/sequel/lathe'

module Sequel #:nodoc:
class Model #:nodoc:
extend Machinist::Machinable

def self.blueprint_class
Machinist::Sequel::Blueprint
end

attr_accessor :machinist_deferred_associations
end
end
22 changes: 22 additions & 0 deletions lib/machinist/sequel/blueprint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Machinist::Sequel
class Blueprint < Machinist::Blueprint
# Make and save an object.
def make!(attributes = {})
object = make(attributes)
object.save(:raise_on_failure => true)

deferred_associations = object.machinist_deferred_associations
if deferred_associations
deferred_associations.each do |association, array|
array.each {|e| object.send(association.add_method, e) }
end
end

object
end

def lathe_class #:nodoc:
Machinist::Sequel::Lathe
end
end
end
35 changes: 35 additions & 0 deletions lib/machinist/sequel/lathe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Machinist::Sequel
class Lathe < Machinist::Lathe
def make_one_value(attribute, args) #:nodoc:
if block_given?
raise_argument_error(attribute) unless args.empty?
yield
else
make_association(attribute, args)
end
end

def make_association(attribute, args) #:nodoc:
association = @klass.association_reflection(attribute)
if association
association.associated_class.make(*args)
else
raise_argument_error(attribute)
end
end

def assign_attribute(attribute, value)
association = @klass.association_reflection(attribute)
if association
if association.returns_array?
(object.machinist_deferred_associations ||= []) << [association, value]
elsif value.new?
value.save(:raise_on_failure => true)
super
end
else
super
end
end
end
end
1 change: 1 addition & 0 deletions machinist.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

s.add_development_dependency "activerecord"
s.add_development_dependency "sequel"
s.add_development_dependency "mysql"
s.add_development_dependency "rake"
s.add_development_dependency "rcov"
Expand Down
2 changes: 1 addition & 1 deletion spec/active_record_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
username { "user_#{sn}" }
end
Post.blueprint do
author { User.make(:username => "post_author_#{sn}") }
author { ActiveRecordEnvironment::User.make(:username => "post_author_#{sn}") }
end
post = Post.make!
post.should be_a(Post)
Expand Down
108 changes: 108 additions & 0 deletions spec/sequel_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
require File.dirname(__FILE__) + '/spec_helper'
require 'support/sequel_environment'

describe Machinist::Sequel do
include SequelEnvironment

before(:each) do
empty_database!
end

context "make" do
it "returns an unsaved object" do
Post.blueprint { }
post = Post.make
post.should be_a(Post)
post.should be_new
end
end

context "make!" do
it "makes and saves objects" do
Post.blueprint { }
post = Post.make!
post.should be_a(Post)
post.should_not be_new
end

it "raises an exception for an invalid object" do
User.blueprint { }
lambda {
User.make!(:username => "")
}.should raise_error(Sequel::ValidationFailed)
end
end

context "associations support" do
it "handles many_to_one associations" do
User.blueprint do
username { "user_#{sn}" }
end
Post.blueprint do
author
end
post = Post.make!
post.should be_a(Post)
post.should_not be_new
post.author.should be_a(User)
post.author.should_not be_new
end

it "handles one_to_many associations" do
Post.blueprint do
comments(3)
end
Comment.blueprint { }
post = Post.make!
post.should be_a(Post)
post.should_not be_new
post.should have(3).comments
post.comments.each do |comment|
comment.should be_a(Comment)
comment.should_not be_new
end
end

it "handles many_to_many associations" do
Post.blueprint do
tags(3)
end
Tag.blueprint do
name { "tag_#{sn}" }
end
post = Post.make!
post.should be_a(Post)
post.should_not be_new
post.should have(3).tags
post.tags.each do |tag|
tag.should be_a(Tag)
tag.should_not be_new
end
end

it "handles overriding associations" do
User.blueprint do
username { "user_#{sn}" }
end
Post.blueprint do
author { SequelEnvironment::User.make(:username => "post_author_#{sn}") }
end
post = Post.make!
post.should be_a(Post)
post.should_not be_new
post.author.should be_a(User)
post.author.should_not be_new
post.author.username.should =~ /^post_author_\d+$/
end
end

context "error handling" do
it "raises an exception for an attribute with no value" do
User.blueprint { username }
lambda {
User.make
}.should raise_error(ArgumentError)
end
end

end
33 changes: 17 additions & 16 deletions spec/support/active_record_environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,27 @@
end
end

class User < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username
end

class Post < ActiveRecord::Base
has_many :comments
belongs_to :author, :class_name => "User"
has_and_belongs_to_many :tags
end
module ActiveRecordEnvironment

class Comment < ActiveRecord::Base
belongs_to :post
end
class User < ActiveRecord::Base
validates_presence_of :username
validates_uniqueness_of :username
end

class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class Post < ActiveRecord::Base
has_many :comments
belongs_to :author, :class_name => "User"
has_and_belongs_to_many :tags
end

module ActiveRecordEnvironment
class Comment < ActiveRecord::Base
belongs_to :post
end

class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end

def empty_database!
[User, Post, Comment].each do |klass|
Expand Down
73 changes: 73 additions & 0 deletions spec/support/sequel_environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'sequel'
require 'sequel/extensions/migration'
require 'machinist/sequel'

DB = Sequel.mysql(:database => 'machinist')

Sequel.migration do
change do
create_table! :users do
primary_key :id
String :username
end

create_table! :posts do
primary_key :id
String :title
Integer :author_id
String :body, :text => true
end

create_table! :comments do
primary_key :id
Integer :post_id
String :body, :text => true
end

create_table! :tags do
primary_key :id
String :name
end

create_table! :posts_tags do
Integer :post_id
Integer :tag_id
end
end
end


module SequelEnvironment

class User < Sequel::Model
plugin :validation_helpers

def validate
super
validates_presence :username
validates_unique :username
end
end

class Post < Sequel::Model
one_to_many :comments
many_to_one :author, :class_name => "SequelEnvironment::User"
many_to_many :tags
end

class Comment < Sequel::Model
many_to_one :post
end

class Tag < Sequel::Model
many_to_many :posts
end

def empty_database!
[User, Post, Comment].each do |klass|
klass.delete
klass.clear_blueprints!
end
end

end