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

Making associations nicer #29

Merged
merged 3 commits into from Oct 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/active_data/model/associations.rb
Expand Up @@ -2,18 +2,19 @@
require 'active_data/model/associations/collection/embedded'

require 'active_data/model/associations/reflections/base'
require 'active_data/model/associations/reflections/embed_reflection'
require 'active_data/model/associations/reflections/singular'
require 'active_data/model/associations/reflections/embeds_any'
require 'active_data/model/associations/reflections/embeds_one'
require 'active_data/model/associations/reflections/embeds_many'
require 'active_data/model/associations/reflections/reference_reflection'
require 'active_data/model/associations/reflections/references_any'
require 'active_data/model/associations/reflections/references_one'
require 'active_data/model/associations/reflections/references_many'

require 'active_data/model/associations/base'
require 'active_data/model/associations/embed_association'
require 'active_data/model/associations/embeds_any'
require 'active_data/model/associations/embeds_one'
require 'active_data/model/associations/embeds_many'
require 'active_data/model/associations/reference_association'
require 'active_data/model/associations/references_any'
require 'active_data/model/associations/references_one'
require 'active_data/model/associations/references_many'

Expand Down
@@ -1,7 +1,7 @@
module ActiveData
module Model
module Associations
class EmbedAssociation < Base
class EmbedsAny < Base
private

def build_object(attributes)
Expand Down
2 changes: 1 addition & 1 deletion lib/active_data/model/associations/embeds_many.rb
@@ -1,7 +1,7 @@
module ActiveData
module Model
module Associations
class EmbedsMany < EmbedAssociation
class EmbedsMany < EmbedsAny
def build(attributes = {})
push_object(build_object(attributes))
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_data/model/associations/embeds_one.rb
@@ -1,7 +1,7 @@
module ActiveData
module Model
module Associations
class EmbedsOne < EmbedAssociation
class EmbedsOne < EmbedsAny
attr_reader :destroyed

def build(attributes = {})
Expand Down
Expand Up @@ -25,6 +25,10 @@ def build(attributes)
data_source.new(attributes)
end

def persist(object, raise_error: false)
raise_error ? object.save! : object.save
end

def scope(owner, source)
scope = data_source.unscoped

Expand Down
Expand Up @@ -15,6 +15,10 @@ def build(_attributes)
raise NotImplementedError, 'Should be implemented in inhereted adapter. Build new instance of data object by attributes'
end

def persist(_object, *)
raise NotImplementedError, 'Should be implemented in inhereted adapter. Build new instance of data object by attributes'
end

def scope(_owner, _source)
raise NotImplementedError, 'Should be implemented in inhereted adapter. Better to be Enumerable'
end
Expand Down
@@ -1,7 +1,7 @@
module ActiveData
module Model
module Associations
class ReferenceAssociation < Base
class ReferencesAny < Base
def scope(source = read_source)
reflection.persistence_adapter.scope(owner, source)
end
Expand All @@ -11,6 +11,10 @@ def scope(source = read_source)
def build_object(attributes)
reflection.persistence_adapter.build(attributes)
end

def persist_object(object, **options)
reflection.persistence_adapter.persist(object, **options)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/active_data/model/associations/references_many.rb
@@ -1,7 +1,7 @@
module ActiveData
module Model
module Associations
class ReferencesMany < ReferenceAssociation
class ReferencesMany < ReferencesAny
def apply_changes
present_keys = target.reject(&:marked_for_destruction?).map do |obj|
reflection.persistence_adapter.identify(obj)
Expand Down
10 changes: 6 additions & 4 deletions lib/active_data/model/associations/references_one.rb
@@ -1,25 +1,27 @@
module ActiveData
module Model
module Associations
class ReferencesOne < ReferenceAssociation
class ReferencesOne < ReferencesAny
def build(attributes = {})
self.target = build_object(attributes)
end

def create(attributes = {})
build(attributes).tap(&:save)
persist_object(build(attributes))
target
end

def create!(attributes = {})
build(attributes).tap(&:save!)
persist_object(build(attributes), raise_error: true)
target
end

def apply_changes
if target
if target.marked_for_destruction? && reflection.autosave?
target.destroy
elsif target.new_record? || (reflection.autosave? && target.changed?)
target.save
persist_object(target)
else
true
end
Expand Down
4 changes: 4 additions & 0 deletions lib/active_data/model/associations/reflections/base.rb
Expand Up @@ -75,6 +75,10 @@ def default(object)
defaultizer
end
end

def collection?
true
end
end
end
end
Expand Down
Expand Up @@ -2,7 +2,7 @@ module ActiveData
module Model
module Associations
module Reflections
class EmbedReflection < Base
class EmbedsAny < Base
def self.build(target, generated_methods, name, options = {}, &block)
if block
options[:class] = proc do |reflection|
Expand Down Expand Up @@ -32,6 +32,10 @@ def klass
def inspect
"#{self.class.name.demodulize}(#{klass})"
end

def embedded?
true
end
end
end
end
Expand Down
10 changes: 1 addition & 9 deletions lib/active_data/model/associations/reflections/embeds_many.rb
Expand Up @@ -2,22 +2,14 @@ module ActiveData
module Model
module Associations
module Reflections
class EmbedsMany < EmbedReflection
class EmbedsMany < EmbedsAny
def self.build(target, generated_methods, name, options = {}, &block)
if target < ActiveData::Model::Attributes
target.add_attribute(ActiveData::Model::Attributes::Reflections::Base, name)
end
options[:validate] = true unless options.key?(:validate)
super
end

def collection?
true
end

def embedded?
true
end
end
end
end
Expand Down
30 changes: 3 additions & 27 deletions lib/active_data/model/associations/reflections/embeds_one.rb
Expand Up @@ -2,40 +2,16 @@ module ActiveData
module Model
module Associations
module Reflections
class EmbedsOne < EmbedReflection
class EmbedsOne < EmbedsAny
include Singular

def self.build(target, generated_methods, name, options = {}, &block)
if target < ActiveData::Model::Attributes
target.add_attribute(ActiveData::Model::Attributes::Reflections::Base, name)
end
options[:validate] = true unless options.key?(:validate)
super
end

def self.generate_methods(name, target)
super

target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def build_#{name} attributes = {}
association(:#{name}).build(attributes)
end

def create_#{name} attributes = {}
association(:#{name}).create(attributes)
end

def create_#{name}! attributes = {}
association(:#{name}).create!(attributes)
end
RUBY
end

def collection?
false
end

def embedded?
true
end
end
end
end
Expand Down
Expand Up @@ -2,7 +2,7 @@ module ActiveData
module Model
module Associations
module Reflections
class ReferenceReflection < Base
class ReferencesAny < Base
def self.build(_target, generated_methods, name, *args)
reflection = new(name, *args)
generate_methods name, generated_methods
Expand Down
Expand Up @@ -2,7 +2,7 @@ module ActiveData
module Model
module Associations
module Reflections
class ReferencesMany < ReferenceReflection
class ReferencesMany < ReferencesAny
def self.build(target, generated_methods, name, *args, &block)
reflection = super

Expand All @@ -14,10 +14,6 @@ def self.build(target, generated_methods, name, *args, &block)
reflection
end

def collection?
true
end

def reference_key
@reference_key ||= options[:reference_key].presence.try(:to_sym) ||
:"#{name.to_s.singularize}_#{primary_key.to_s.pluralize}"
Expand Down
26 changes: 3 additions & 23 deletions lib/active_data/model/associations/reflections/references_one.rb
Expand Up @@ -2,7 +2,9 @@ module ActiveData
module Model
module Associations
module Reflections
class ReferencesOne < ReferenceReflection
class ReferencesOne < ReferencesAny
include Singular

def self.build(target, generated_methods, name, *args, &block)
reflection = super

Expand All @@ -14,28 +16,6 @@ def self.build(target, generated_methods, name, *args, &block)
reflection
end

def self.generate_methods(name, target)
super

target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def build_#{name} attributes = {}
association(:#{name}).build(attributes)
end

def create_#{name} attributes = {}
association(:#{name}).create(attributes)
end

def create_#{name}! attributes = {}
association(:#{name}).create!(attributes)
end
RUBY
end

def collection?
false
end

def reference_key
@reference_key ||= options[:reference_key].presence.try(:to_sym) ||
:"#{name}_#{primary_key}"
Expand Down
35 changes: 35 additions & 0 deletions lib/active_data/model/associations/reflections/singular.rb
@@ -0,0 +1,35 @@
module ActiveData
module Model
module Associations
module Reflections
module Singular
extend ActiveSupport::Concern

module ClassMethods
def generate_methods(name, target)
super

target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def build_#{name} attributes = {}
association(:#{name}).build(attributes)
end

def create_#{name} attributes = {}
association(:#{name}).create(attributes)
end

def create_#{name}! attributes = {}
association(:#{name}).create!(attributes)
end
RUBY
end
end

def collection?
false
end
end
end
end
end
end