-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e9a08f4
commit f163ed1
Showing
7 changed files
with
263 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,65 @@ | |||
require 'active_record' | |||
require 'sqlite3' | |||
|
|||
ActiveRecord::Base.establish_connection( | |||
adapter: 'sqlite3', | |||
database: 'db/test.db' | |||
) | |||
|
|||
%w(posts blogs comments).each do |table| | |||
ActiveRecord::Base.connection.execute( | |||
%( | |||
DROP TABLE | |||
IF EXISTS | |||
#{table} | |||
) | |||
) | |||
end | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
posts( | |||
id INTEGER, | |||
blog_id INTEGER, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
blogs( | |||
id INTEGER, | |||
name VARCHAR, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
comments( | |||
id INTEGER, | |||
post_id INTEGER, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
|
|||
class Post < ActiveRecord::Base | |||
belongs_to :blog | |||
has_many :comments | |||
end | |||
|
|||
class Blog < ActiveRecord::Base | |||
has_many :posts | |||
end | |||
|
|||
class Comment < ActiveRecord::Base | |||
belongs_to :post | |||
end | |||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,63 @@ | |||
module Frill | |||
module ActiveRecord | |||
class AssociationDecorator | |||
def self.decorate(object, context) | |||
new(object, context).decorate | |||
end | |||
|
|||
def initialize(object, context) | |||
@object = object | |||
@context = context | |||
end | |||
|
|||
def decorate | |||
embed_context_in_object | |||
decorate_associations | |||
end | |||
|
|||
private | |||
def embed_context_in_object | |||
frill_context = @context | |||
|
|||
object.extend( | |||
Module.new do | |||
private | |||
define_method(:__frill_context) do | |||
frill_context | |||
end | |||
end | |||
) | |||
end | |||
|
|||
def decorate_associations | |||
object.class.reflect_on_all_associations.each do |association| | |||
if association.collection? | |||
object.extend( | |||
Module.new.tap do |mod| | |||
mod.class_eval <<-EVAL | |||
def #{association.name} | |||
Frill::ActiveRecord::CollectionProxy.new(super, __frill_context) | |||
end | |||
EVAL | |||
end | |||
) | |||
else | |||
object.extend( | |||
Module.new.tap do |mod| | |||
mod.class_eval <<-EVAL | |||
def #{association.name} | |||
association = super | |||
return nil unless association | |||
Frill.decorate association, __frill_context | |||
end | |||
EVAL | |||
end | |||
) | |||
end | |||
end | |||
end | |||
|
|||
attr_reader :object, :context | |||
end | |||
end | |||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
module Frill | |||
module ActiveRecord | |||
class CollectionProxy | |||
def initialize(collection, context) | |||
end | |||
end | |||
end | |||
end | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,113 @@ | |||
require 'active_record' | |||
require 'sqlite3' | |||
|
|||
ActiveRecord::Base.establish_connection( | |||
adapter: 'sqlite3', | |||
database: 'db/test.db' | |||
) | |||
|
|||
%w(posts blogs comments).each do |table| | |||
ActiveRecord::Base.connection.execute( | |||
%( | |||
DROP TABLE | |||
IF EXISTS | |||
#{table} | |||
) | |||
) | |||
end | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
posts( | |||
id INTEGER, | |||
blog_id INTEGER, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
blogs( | |||
id INTEGER, | |||
name VARCHAR, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
ActiveRecord::Base.connection.execute( | |||
%( | |||
CREATE TABLE | |||
comments( | |||
id INTEGER, | |||
post_id INTEGER, | |||
PRIMARY KEY(id ASC) | |||
) | |||
) | |||
) | |||
|
|||
require_relative '../lib/frill/active_record/association_decorator' | |||
|
|||
class Post < ActiveRecord::Base | |||
belongs_to :blog | |||
has_many :comments | |||
end | |||
|
|||
class Blog < ActiveRecord::Base | |||
has_many :posts | |||
end | |||
|
|||
class Comment < ActiveRecord::Base | |||
belongs_to :post | |||
end | |||
|
|||
describe Frill::ActiveRecord::AssociationDecorator do | |||
before { Post.destroy_all; Blog.destroy_all; Comment.destroy_all } | |||
before { Frill.reset! } | |||
|
|||
let!(:post) do | |||
Post.create.tap do |p| | |||
p.blog = Blog.create | |||
p.save | |||
end | |||
end | |||
|
|||
let!(:decorated_module) do | |||
Module.new do | |||
include Frill | |||
|
|||
def self.frill?(*) | |||
true | |||
end | |||
end | |||
end | |||
|
|||
describe ".decorate(object, context)" do | |||
context "given an ActiveRecord object" do | |||
it "should decorate associated objects" do | |||
Frill::ActiveRecord::AssociationDecorator.decorate post, double(:context) | |||
blog_eigenclass = class << post.blog; self; end | |||
blog_eigenclass.included_modules.should include decorated_module | |||
end | |||
|
|||
it "should not attempt to decorate nil associations" do | |||
comment = Comment.create | |||
Frill::ActiveRecord::AssociationDecorator.decorate comment, double(:context) | |||
post_eigenclass = class << comment.post; self; end | |||
post_eigenclass.included_modules.should_not include decorated_module | |||
end | |||
|
|||
it "should lazily decorate collection associations" do | |||
post.comments << Comment.create << Comment.create | |||
Frill::ActiveRecord::AssociationDecorator.decorate post, double(:context) | |||
comments = post.comments | |||
comment = comments.first | |||
comment_eigenclass = class << comment; self; end | |||
comment_eigenclass.included_modules.should include decorated_module | |||
end | |||
end | |||
end | |||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
require_relative '../../../../lib/frill/active_record/association_proxy' | |||
|
|||
module Frill | |||
module ActiveRecord | |||
describe CollectionProxy do | |||
|
|||
end | |||
end | |||
end |