Module: Her::Model::Relationships::ClassMethods

Defined in:
lib/her/model/relationships.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(name, attrs = {}) ⇒ Object

Define a belongs_to relationship.

Examples:

class User
  include Her::API
  belongs_to :team, :class_name => "Group"
end

class Group
  include Her::API
end

@user = User.find(1)
@user.team # => #<Team(teams/2) id=2 name="Developers">
# Fetched via GET "/teams/2"

Parameters:

  • name (Symbol)

    The name of the model

  • attrs (Hash) (defaults to: {})

    Options (currently not used)



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/her/model/relationships.rb', line 159

def belongs_to(name, attrs={})
  attrs = {
    :class_name => name.to_s.classify,
    :name => name,
    :foreign_key => "#{name}_id",
    :path => "/#{name.to_s.pluralize}/:id"
  }.merge(attrs)
  (relationships[:belongs_to] ||= []) << attrs

  define_method(name) do |*method_attrs|
    method_attrs = method_attrs[0] || {}
    klass = self.class.nearby_class(attrs[:class_name])
    if method_attrs.any?
      klass.get_resource("#{klass.build_request_path(method_attrs.merge(:id => @data[attrs[:foreign_key].to_sym]))}")
    else
      @data[name] ||= klass.get_resource("#{klass.build_request_path(:id => @data[attrs[:foreign_key].to_sym])}")
    end
  end
end

#has_many(name, attrs = {}) ⇒ Object

Define an has_many relationship.

Examples:

class User
  include Her::API
  has_many :articles
end

class Article
  include Her::API
end

@user = User.find(1)
@user.articles # => [#<Article(articles/2) id=2 title="Hello world.">]
# Fetched via GET "/users/1/articles"

Parameters:

  • name (Symbol)

    The name of the model

  • attrs (Hash) (defaults to: {})

    Options (currently not used)



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/her/model/relationships.rb', line 73

def has_many(name, attrs={})
  attrs = {
    :class_name     => name.to_s.classify,
    :name           => name,
    :path           => "/#{name}",
    :inverse_of => nil
  }.merge(attrs)
  (relationships[:has_many] ||= []) << attrs

  define_method(name) do |*method_attrs|
    method_attrs = method_attrs[0] || {}
    klass = self.class.nearby_class(attrs[:class_name])
    if method_attrs.any?
      @data[name] = klass.get_collection("#{self.class.build_request_path(method_attrs.merge(:id => id))}#{attrs[:path]}")
    else
      @data[name] ||= klass.get_collection("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
    end

    inverse_of = if attrs[:inverse_of]
                       attrs[:inverse_of]
                    else
                     self.class.name.split('::').last.tableize.singularize
                   end
    @data[name].each do |entry|
      entry.send("#{inverse_of}=", self)
    end

    @data[name]
  end
end

#has_one(name, attrs = {}) ⇒ Object

Define an has_one relationship.

Examples:

class User
  include Her::API
  has_one :organization
end

class Organization
  include Her::API
end

@user = User.find(1)
@user.organization # => #<Organization(organizations/2) id=2 name="Foobar Inc.">
# Fetched via GET "/users/1/organization"

Parameters:

  • name (Symbol)

    The name of the model

  • attrs (Hash) (defaults to: {})

    Options (currently not used)



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/her/model/relationships.rb', line 122

def has_one(name, attrs={})
  attrs = {
    :class_name => name.to_s.classify,
    :name => name,
    :path => "/#{name}"
  }.merge(attrs)
  (relationships[:has_one] ||= []) << attrs

  define_method(name) do |*method_attrs|
    method_attrs = method_attrs[0] || {}
    klass = self.class.nearby_class(attrs[:class_name])
    if method_attrs.any?
      klass.get_resource("#{self.class.build_request_path(method_attrs.merge(:id => id))}#{attrs[:path]}")
    else
      @data[name] ||= klass.get_resource("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
    end
  end
end

#parse_relationships(data) ⇒ Object

Parse relationships data after initializing a new object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/her/model/relationships.rb', line 36

def parse_relationships(data)
  relationships.each_pair do |type, definitions|
    definitions.each do |relationship|
      name = relationship[:name]
      next unless data[name]
      klass = self.nearby_class(relationship[:class_name])
      data[name] = case type
        when :has_many
          Her::Model::ORM.initialize_collection(klass, :data => data[name])
        when :has_one, :belongs_to
          klass.new(klass.parse(data[name]))
        else
          nil
      end
    end
  end
  data
end

#relationship_accessor(type, attrs) ⇒ Object



180
181
182
183
184
185
186
187
# File 'lib/her/model/relationships.rb', line 180

def relationship_accessor(type, attrs)
  name = attrs[:name]
  class_name = attrs[:class_name]
  define_method(name) do
    klass = self.class.nearby_class(attrs[:class_name])
    @data[name] ||= klass.get_resource("#{klass.build_request_path(attrs[:path], :id => @data[attrs[:foreign_key].to_sym])}")
  end
end

#relationshipsObject

Return @her_relationships, lazily initialized with copy of the superclass’ her_relationships, or an empty hash.



23
24
25
26
27
28
29
30
31
# File 'lib/her/model/relationships.rb', line 23

def relationships
  @her_relationships ||= begin
    if superclass.respond_to?(:relationships)
      superclass.relationships.dup
    else
      {}
    end
  end
end