Class: DataActive::Entity

Inherits:
Object
  • Object
show all
Defined in:
lib/data_active/entity.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tag_name, options = [], excluded = false) ⇒ Entity

Returns a new instance of Entity.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/data_active/entity.rb', line 13

def initialize(tag_name, options = [], excluded = false)
  @tag_name = tag_name
  @options = options
  @attributes = {}
  @associations = {}
  @excluded = excluded

  unless @excluded
    begin
      @klass = Kernel.const_get(@tag_name.camelize)
      raise "Class '#{@tag_name.camelize}' is not inherit ActiveRecord" unless @klass.ancestors.include? ActiveRecord::Base
      @associations = Hash[@klass.reflect_on_all_associations.map { |a| [a.plural_name.to_sym, a] }]
      @record = @klass.new
    rescue
      @excluded = true
    end
  end
end

Instance Attribute Details

#associationsObject (readonly)

Returns the value of attribute associations.



7
8
9
# File 'lib/data_active/entity.rb', line 7

def associations
  @associations
end

#attributesObject (readonly)

Returns the value of attribute attributes.



5
6
7
# File 'lib/data_active/entity.rb', line 5

def attributes
  @attributes
end

#belongs_toObject

Returns the value of attribute belongs_to.



9
10
11
# File 'lib/data_active/entity.rb', line 9

def belongs_to
  @belongs_to
end

#excludedObject

Returns the value of attribute excluded.



11
12
13
# File 'lib/data_active/entity.rb', line 11

def excluded
  @excluded
end

#klassObject (readonly)

Returns the value of attribute klass.



6
7
8
# File 'lib/data_active/entity.rb', line 6

def klass
  @klass
end

#recordObject

Returns the value of attribute record.



10
11
12
# File 'lib/data_active/entity.rb', line 10

def record
  @record
end

#tag_nameObject (readonly)

Returns the value of attribute tag_name.



8
9
10
# File 'lib/data_active/entity.rb', line 8

def tag_name
  @tag_name
end

Instance Method Details

#commitObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/data_active/entity.rb', line 50

def commit
  id = nil
  existing_record = find_existing
  @attributes.delete(@klass.primary_key.to_s)

  if existing_record.nil? and options_include? :any, [:create, :sync]
    id = save
  elsif existing_record.present? and options_include? :any, [:update, :sync]
    @record = existing_record
    id = save
  elsif options_include? :any, [:destroy, :sync]
    id = @record.attributes[@klass.primary_key.to_s]
  end

  id
end

#commit_attributesObject



145
146
147
148
149
# File 'lib/data_active/entity.rb', line 145

def commit_attributes
  @attributes.each do |key, a|
    @record.__send__("#{a.name}=", a.content)
  end
end

#find_existingObject



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/data_active/entity.rb', line 107

def find_existing
  existing_record = nil

  begin
    existing_record = @klass.find(@attributes[@klass.primary_key.to_s].content) if @attributes[@klass.primary_key.to_s].present?
  rescue
    existing_record = nil
  end

  existing_record
end

#foreign_key_from(association) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/data_active/entity.rb', line 94

def foreign_key_from(association)
  if ActiveRecord::Reflection::AssociationReflection.method_defined? :foreign_key
    # Support for Rails 3.1 and later
    foreign_key = association.foreign_key
  elsif ActiveRecord::Reflection::AssociationReflection.method_defined? :primary_key_name
    # Support for Rails earlier than 3.1
    foreign_key = association.primary_key_name
  else
    raise 'Unsupported version of ActiveRecord. Unable to identify the foreign key.'
  end
  foreign_key
end

#has_association_with?(name) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/data_active/entity.rb', line 46

def has_association_with?(name)
  @associations.has_key? name.pluralize.to_sym
end

#has_attribute?(name) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
# File 'lib/data_active/entity.rb', line 38

def has_attribute?(name)
  if @excluded
    false
  else
    @record.attributes.include? name
  end
end

#options_include?(context, options) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
# File 'lib/data_active/entity.rb', line 33

def options_include? (context, options)
  ((@options & options).count.eql? options.count and  context.eql? :all) ||
    ((@options & options).count > 0 and  context.eql? :any)
end

#saveObject



119
120
121
122
123
124
125
126
127
# File 'lib/data_active/entity.rb', line 119

def save
  commit_attributes
  update_associations

  if will_violate_association?
    @record.save!
    @record.attributes[@klass.primary_key.to_s]
  end
end

#update_associationsObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/data_active/entity.rb', line 67

def update_associations
  if belongs_to.present? and not belongs_to.excluded
    association = belongs_to.klass.reflect_on_all_associations.select { |a| a.plural_name == @klass.name.underscore.pluralize }[0]
    if belongs_to.record.new_record?
      existing = belongs_to.find_existing
      belongs_to.record = existing if existing.present?
    end

    if belongs_to.record.new_record?
      case association.macro
        when :has_many, :has_many_and_blongs_to
          belongs_to.record.__send__(association.name) << @record

        when :has_one
          belongs_to.record.__send__("#{association.name}=", @record)

        else
          raise "unsupported association #{association.macro} for #{association.name} on #{@klass.name}"

      end
    else
      foreign_key = foreign_key_from(association)
      @record.__send__("#{foreign_key}=", belongs_to.record.__send__(belongs_to.klass.primary_key.to_sym))
    end
  end
end

#will_violate_association?Boolean

Returns:

  • (Boolean)


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/data_active/entity.rb', line 129

def will_violate_association?
  ok = true
  if belongs_to.present? and belongs_to.associations.count > 0
    if belongs_to.associations[@tag_name.pluralize.to_sym].macro == :has_one
      existing = belongs_to.record.__send__(@tag_name)
      if existing.present?
        if @record.__send__(@klass.primary_key.to_s) != existing.__send__(@klass.primary_key.to_s)
          ok = false
        end
      end
    end
  end

  ok
end