-
Notifications
You must be signed in to change notification settings - Fork 182
define methods for properties and associations getter/setter #300
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
define methods for properties and associations getter/setter #300
Conversation
I like the change. There does seem to be quite a bit of style change embedded in this PR though. I'd suggest splitting out the feature change from the code style changes. To explain that a little more: Given the lack of documentation on this project, that means folks often rely on reading the source code to find their answer. As a result the code-style being uniform has a greater impact on library comprehension. - If you want to suggest the style changes, we probably would want to do it across the library. |
Thanks for your work! These are solid changes. It may be easier to read & test if that code is contained in a single module. The way i've done it before it to have an module JsonApiClient
module Associatable
extend ActiveSupport::Concern
included do
class_attribute :__associations
self.__associations = {}
attr_accessor :__cached_associations
class << self
def belongs_to( name, opts = {} )
process Associations::BelongsTo.new( self, name, opts )
end
def has_one( name, opts = {} )
process Associations::HasOne.new( self, name, opts )
end
def has_many( name, opts = {} )
process Associations::HasMany.new( self, name, opts )
end
protected
def process( association )
associate association
methodize association
end
def associate( association )
self.__associations = __associations.merge association.name => association
end
def methodize( association )
define_method association.name do
self.__cached_associations ||= {}
unless self.__cached_associations.has_key? association.name
self.send( "#{association.name}=", association.fetch( self ) )
end
self.__cached_associations[association.name]
end
define_method "#{association.name}=" do | value |
self.__cached_associations ||= {}
self.__cached_associations[association.name] = value
end
end
end
end
end
end Does that make sense? Functionally, again, this is solid. |
@jsmestad thanks for your review. I agree with you. I'll remove style changes and introduce styling refactor MR later. |
@gaorlov thanks for your review. I agree that code will be more readable if we move associations logic into separate concern. |
How can I help? |
f5941c5
to
85ee5f9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks really solid. My only comment is whether we need some code in method_missing
. Nicely done.
nil | ||
end | ||
|
||
def method_missing(method, *args) | ||
association = association_for(method) | ||
relationship_definition = relationship_definition_for(method) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since creating an association generates the accessor methods, will a relationship ever get into method_missing
?
If not, do we need this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaorlov, I've changed it. Take a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Nicely done.
|
||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, man.
That's so much nicer to read! Strong work!
85ee5f9
to
8d3c942
Compare
8d3c942
to
3048ea3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks solid
Description
It's a bad practice to dynamically create methods when accessing method missing, so I changed a behavior of of static define attributes.
Generally I add accessors for each attribute that defined with
property
class method and relactionships that defined withhas_one
,has_many
, andbelongs_to
class methodsperformance may be decreased comparing to previous version unless you define
properties
for all accessed attributes