-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Conditional attributes/associations (if/unless) #1403
Conversation
6ea8dcb
to
bcd428e
Compare
def include?(serializer) | ||
case condition_type | ||
when :if | ||
serializer.send(condition) |
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.
public_send
?
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.
Just updated it.
Looks like a good approach to me. |
class Serializer | ||
Attribute = Struct.new(:name, :block, :key, :condition_type, :condition) do | ||
def initialize(name, block, options) | ||
super(name, block) |
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 the :key, :condition_type, :condition
attributes to an initializer lumped as options
(which I initially missed), why not just take in options and create our own accessors for key, condition_type, condition?
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.
That's indeed a possibility. The rationale was to do the work only once.
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.
By 'work' you mean defining accessors for the options? Ok, I get that. I think I'd rather add an attr_accessor than change the Struct definition if I needed to change the options. It took me a couple of reads of the object before I realized you were treating most of the struct attributes as options. (I'm not new to subclassing the initialize... I just usually use it for setting defaults for unset values, rather than as implicit accessors).
Do you foresee taking advantage of the struct's comparable properties? I'm trying to balance the clever vs. useful in my head.
Also ref #1333 |
755516b
to
d2887a2
Compare
d2887a2
to
7bc66c5
Compare
dc3e8e3
to
92dd9b6
Compare
|
||
def condition | ||
options[condition_type] | ||
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.
yet another sign there's a common ancestor or module
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.
Agreed, we could either make a Field
class from which Attribute
and Reflection
would inheritate, or a ConditionalField
mixin. Not sure what's best, and naming is obviously up for debate.
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.
I think regular inheritance makes sense in this case (if we include more than just the if/else)
Looking good.. let's finish #1370 and add some tests and docs here :) |
30b8d33
to
0641f25
Compare
@@ -0,0 +1,40 @@ | |||
module ActiveModel | |||
class Serializer | |||
Field = Struct.new(:name, :options, :block) do |
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.
Kept it as a struct because tests in test/serializers/association_macros_test.rb
made use of the comparability. Wouldn't mind modifying those in a subsequent PR.
5bc8eea
to
656b232
Compare
PR ready. |
@@ -0,0 +1,56 @@ | |||
module ActiveModel | |||
class Serializer | |||
# Holds all the meta-data about a field (i.e. attribute or association) as it was |
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.
grammar: s/i.e./e.g.
reason: meaning is to change 'that is' to 'for example'
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.
I actually meant i.e., because I'm just defining what "field" means.
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.
still think it should be e.g., but since it's intentional on your part and it's super unimportant, ok to merge when green
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.
Agreed that it's not super important, but as I like grammar as well: a field is defined as "either an attribute or an association".
@beauby two small comments, one grammar, one internal api. 💯 LGTM |
Is the support for if/unless already implemented in the master? I don't want my subjects association to be included when the controller method is index
But I get the error undefined method `index' for #<Admin::SemesterSerializer |
@Mohakjuneja the serializer doesn't have access to the controller's methods, as the passed in scope defaults to Have you seen these docs? https://github.com/rails-api/active_model_serializers/blob/master/docs/general/serializers.md#scope maybe they could help? |
I figured it out! I apologize for being impatient and posting the issue too soon. AMS has consumed a lot of my time upgrading from 0.9.3 to the master. Thank you! |
what did you do? (for those who may come by this issue in the future with the same problem?) |
I added the
And in the serializer, I accessed it using the |
You would win many friends and much karma if you could help us write an updating guide! ref: #1005 |
@bf4 I'm starting up my own venture (wish me luck!) but I'll be glad to help you with it! This community has been very supportive :) |
I was able to determine the view by adding this to my controller
|
It stopped working all of a sudden.
What just happened? |
You need a comma before your |
I found the error. But I don't know how to correct it. It's not working for this syntax anymore Does that mean I need to write another line for :subject_name? |
|
I'm sorry about taking so much of your time but I've tried everything |
so maybe you do need to define each attribute on it's own line with it's own if condition, so:
|
I'll do that for now but I don't find that a very effective solution. We may need to take a look at it. Also I don't know why it worked two days ago but doesn't work anymore. Thank you @NullVoxPopuli :) |
@Mohakjuneja that's what version control is for :) Let me know if I'm summarizing this correctly (ignoring syntax errors), then please open a new issue if we need further discussion. works attribute :total, if: :view_uploads?
attribute :subject_name, if: :view_uploads? desired, doesn't work attributes :total, :subject_name, if: :view_uploads? |
@bf4 I've been thinking about the current syntax and I'm wondering if we should stick to it.
What is your opinion about that? |
I'd much rather allow lambdas as |
Adding documentation and short example ([from this pull request](rails-api#1403)) on conditional attributes.
Adding documentation and short example ([from this pull request](rails-api#1403)) on conditional attributes. Adding lambda literal notation and example. Adding lambda literal notation and example, and fixing typo. Removing PR reminder Adding Changelog entry Moving CHANGELOG entry under master (unreleased)
Adding documentation and short example ([from this pull request](rails-api#1403)) on conditional attributes. Adding lambda literal notation and example. Adding lambda literal notation and example, and fixing typo. Removing PR reminder Adding Changelog entry Moving CHANGELOG entry under master (unreleased) Use option instead of parameter
the attributes doesn't work with scope if your shown multiple attributes the correct way put it as arry
|
My take at conditional attributes/associations. Previous work has been done in this direction (#1266), but I figured it was easily expressed on top of #1370.
This PR adds support for
if/unless
options to attribute/association definitions in serializers. Those options take a symbol of a method name on the serializer.Example:
Note: if this gets traction, I'll add tests.
Ref #1245, #1266, #1058, #922, #1141