Skip to content

Block for conditional field is always called #49

Open

Description

@ezekg

Example

relationship :user, unless: -> { @object.user.nil? } do
  link :related do
    @url_helpers.v1_user_path @object.user
  end
end

Expected outcome

The relationship block is not called when the conditional fails.

Actual outcome

The relationship block is called regardless of the conditional failing; only the display of the serialized relationship is changed. This requires additional checks within the block, which makes the code less readable (especially for nested resource routes) and duplicates the condition:

relationship :user, unless: -> { @object.user.nil? } do
  link :related do
    @url_helpers.v1_user_path @object.user if @object.user.present?
  end
end

Solution

Do not call the block if the condition fails.


Would you be open to a pull request?

Activity

  1. beauby commented on Dec 21, 2016

    @beauby
    Member

    @ezekg You are right – at the moment links are built eagerly (only the related objects are constructed lazily). However, a simple fix for your use-case (that would be in-line with the spirit of the spec) would be to expose the related user via some nested route (like /posts/3/user), rather than the canonical resource url (/users/:id).

    Regarding the former, I am currently refactoring that part to avoid eagerly building stuff, so it should be fixed for the next release.

  2. beauby commented on Dec 22, 2016

    @beauby
    Member

    @ezekg See json-api/json-api#1134 and related issues for an overview of why exposing the related link as /posts/3/user is the most flexible solution.

  3. ezekg commented on Dec 22, 2016

    @ezekg
    Author

    As much as I'd like to implement that, at the moment it brings in too much overhead into developing the API. I'd need to create new routes/controllers for each relationship, and write tests for them.

    Appreciate the guidance though. I'm going to create a ticket as a reminder to come back to this.

  4. beauby commented on Feb 17, 2017

    @beauby
    Member

    @ezekg Would you mind writing a regression test for this?

  5. ezekg commented on Feb 17, 2017

    @ezekg
    Author

    Definitely. I'll try and do that this weekend.

  6. dylanlewis89 commented on Jul 24, 2017

    @dylanlewis89

    Out of curiosity, does the library currently support specifying any conditional rendering of attributes in the serializer via the exposed instance variables?

    For example:

    class SerializableBar < JSONAPI::Serializable::Resource
      type 'bars'
    
      attribute :always_show_me
      attribute :conditionally_show_me, unless: -> { @authenticated }
    end
    

    This requested feature was the closest I could find to this and just wanted to see if I was missing anything obvious that already existed in the library.

  7. beauby commented on Jul 24, 2017

    @beauby
    Member

    @dylanlewis89 Yes it does, you just have to call extend JSONAPI::Serializable::Resource::KeyFormat in your serializer in order to enable it.

  8. beauby commented on Jul 24, 2017

    @beauby
    Member

    @dylanlewis89 Sorry, I obviously meant JSONAPI::Serializable::Resource::ConditionalFields rather than JSONAPI::Serializable::Resource::KeyFormat.

  9. dylanlewis89 commented on Jul 25, 2017

    @dylanlewis89

    Thanks @beauby for the quick and helpful response!

    For anyone tackling this issue in the future, the 0.2.1 release introduces the extend JSONAPI::Serializable::Resource::ConditionalFields syntax. Earlier versions use prepend instead of extend

  10. beauby commented on Sep 12, 2017

    @beauby
    Member

    @ezekg So if you're still interested in fixing this, it's just a matter of delaying the instance_evaling here until either as_jsonapi or related_resources are called.

  11. ezekg commented on Oct 4, 2017

    @ezekg
    Author

    Hey, I just updated my API to use the latest version of jsonapi-rb/rails so I can dig into fixing this now! I was trying to hold off until I could get around to updating, as I was still on v0.1.1. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions