Module: Daylight::Associations::ClassMethods
- Defined in:
- lib/daylight/associations.rb
Instance Method Summary collapse
-
#belongs_to(name, options = {}) ⇒ Object
Adds a setter to the original ‘belongs_to` method that uses nested_attributes.
-
#has_many(name, options = {}) ⇒ Object
Support for the :through option so that the server-side handles the association.
-
#has_one(name, options = {}) ⇒ Object
Fix bug in has_one that is not creating the request correctly.
-
#has_one_through(name, options) ⇒ Object
Adds getter and setter methods for ‘has_one` associations that are through a `belongs_to` association.
- #reflection_names ⇒ Object
-
#remote(name, options) ⇒ Object
Adds a method to the model that calls the remote action for its data.
Instance Method Details
#belongs_to(name, options = {}) ⇒ Object
Adds a setter to the original ‘belongs_to` method that uses nested_attributes. Also, hands off the :through option to `belongs_to_through`.
Example:
comment = Comment.find(1)
comment.creator = current_user
See: ActiveResource::Associations#belongs_to
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/daylight/associations.rb', line 94 def belongs_to name, ={} create_reflection(:belongs_to, name, ).tap do |reflection| nested_attribute_key = "#{reflection.name}_attributes" # setup the resource_proxy to fetch the results define_cached_method reflection.name, cache_key: nested_attribute_key do reflection.klass.find(send(reflection.foreign_key)) end # Defines a setter caching the value in an instance variable for later # retrieval. Stash value directly in the attributes using the # nested_attributes functionality server-side. define_method "#{reflection.name}=" do |value| attributes[reflection.foreign_key] = value.id # set the foreign key instance_variable_set(:"@#{reflection.name}", value) # set the cached value end end end |
#has_many(name, options = {}) ⇒ Object
Support for the :through option so that the server-side handles the association.
Post.first.comments #=> GET /posts/1/comments.json
Also adds the setter for assocations:
Post.first.comments = [new_comment]
See: ActiveResource::Associations#has_many
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/daylight/associations.rb', line 57 def has_many name, ={} through = .delete(:use).to_s return super if through == 'resource' create_reflection(:has_many, name, ).tap do |reflection| nested_attribute_key = "#{reflection.name}_attributes" # setup the resource_proxy to fetch the results define_cached_method reflection.name, cache_key: nested_attribute_key do # return a empty collection if this is a new record return self.send("#{reflection.name}=", []) if new? resource_proxy = resource_proxy_for(reflection, self) resource_proxy.from(association_path(reflection)) end # define setter that places the value directly in the attributes using # the nested_attributes functionality server-side define_method "#{reflection.name}=" do |value| instance_variable_set(:"@#{reflection.name}", value) end end end |
#has_one(name, options = {}) ⇒ Object
Fix bug in has_one that is not creating the request correctly. Use ‘where` functionality as it peforms the function that is needed
Allows the has_one :through association.
See: has_one_through
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/daylight/associations.rb', line 196 def has_one(name, = {}) return has_one_through(name, ) if .has_key? :through create_reflection(:has_one, name, ).tap do |reflection| define_cached_method reflection.name do reflection.klass.where(:"#{self.class.element_name}_id" => self.id).first end define_method "#{reflection.name}=" do |value| value.attributes[:"#{self.class.element_name}_id"] = self.id instance_variable_set(:"@#{reflection.name}", value) # set the cached value end end end |
#has_one_through(name, options) ⇒ Object
Adds getter and setter methods for ‘has_one` associations that are through a `belongs_to` association. Assumes that the information about the association is generated in the nested attributes by a HasOneThrough serializer.
In this example, if we did not go through the identity association the primary keys would be generated, but upon save, an error would be thrown because it is an unknown attribute. This only happens with ‘belongs_to` methods as they contain the primary_key.
For example, consider ‘user_id` and `zone_id` primary keys:
class PostSerializer < ActiveModel::Serializer
embed :ids
has_one :blog
has_one :company, :zone through: :blog
end
It will generate the following json:
{
"post": {
"id": 1,
"blog_id": 2,
"blog_attributes": {
"id": 2,
"company_id": 3
}
}
}
An ActiveResource can define ‘belongs_to` with :through to read from nested attributes for fetching by primary_key or setting to save.
class Post < Daylight::API
belongs_to :blog
has_one :company, through: :blog
end
So that:
p = Post.find(1)
p.blog # => #<Blog @attributes={"id"=>1}>
p.company # => #<Company @attributes={"id"=>3}>
And setting these associations will work with passing validations:
p.company = Company.find(1)
p.save # => true
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/daylight/associations.rb', line 166 def has_one_through name, through = .delete(:through).to_s create_reflection(:has_one, name, ).tap do |reflection| nested_attributes_key = "#{reflection.name}_attributes" through_attributes_key = "#{through}_attributes" define_cached_method reflection.name, index: through_attributes_key do reflection.klass.find(attributes[through_attributes_key][reflection.foreign_key]) end define_method "#{reflection.name}=" do |value| through_attributes = attributes["#{through}_attributes"] ||= {} through_attributes[reflection.foreign_key] = value.id through_attributes[nested_attributes_key] = value instance_variable_set(:"@#{reflection.name}", value) end end end |
#reflection_names ⇒ Object
41 42 43 |
# File 'lib/daylight/associations.rb', line 41 def reflection_names reflections.keys.map(&:to_s) end |
#remote(name, options) ⇒ Object
Adds a method to the model that calls the remote action for its data.
Example:
remote :posts_by_popularity, class_name: 'post'
219 220 221 222 223 224 225 |
# File 'lib/daylight/associations.rb', line 219 def remote name, create_reflection(:remote, name, ).tap do |reflection| define_cached_method reflection.name do call_remote(reflection.name, reflection.klass) end end end |