Code Monkey home page Code Monkey logo

Comments (8)

krzkrzkrz avatar krzkrzkrz commented on July 17, 2024 16

Actually, I figured this out. has_many supports blocks. ie.

  has_many :comments do |object, params|
    object.comments.where(status: params[:filter][:status])
  end

from fast_jsonapi.

shishirmk avatar shishirmk commented on July 17, 2024

@gsaks123 we have the ability to customize the object_method_name and id_method_name for a has_many relationship. Here is the documentation https://github.com/Netflix/fast_jsonapi#customizable-options. Have you considered you these options?

from fast_jsonapi.

gsaks123 avatar gsaks123 commented on July 17, 2024

@shishirmk Wow, I completely missed this. Yes, this is exactly the functionality I need. Not only does the object_method_name scope the "relationships" payload, but it also applies (critically) to the "included" payload. Perfect!

Thanks for your work on this gem.

from fast_jsonapi.

krzkrzkrz avatar krzkrzkrz commented on July 17, 2024

@gsaks123 Can you give us an example of how you have it at the moment. Would be great to add some clarity on your current implementation

from fast_jsonapi.

gsaks123 avatar gsaks123 commented on July 17, 2024

Sure. In this scenario we have an object class "Fighter", and when we call our API for a Fighter record, we want it to eager load and include a deeply nested association of other objects. And that association is heavily scoped to only include certain results, with custom ordering.

Here is the custom method on our app/models/fighter.rb class which defines the scoping and the association. We want this logic to be applied to what is returned by our API:

  def ordered_fighter_bouts_api
    relation = fighter_bouts.includes( bout: [ {event: :promotion}, {fighter_bouts: :fighter}, :weight_class ] )
    relation = relation.where(status: Bout::STATUS_VISIBLE, sport: 'mma')
    relation.order("events.starts_at DESC", "bouts.bout_number_at_event DESC NULLS LAST", "bouts.id DESC")
  end

Then, in our serializer for Fighter records, app/serializers/v1/fighter_serializer.rb, we utilize the convenient 'object_method_name' that @shishirmk alerted me to:

class V1::FighterSerializer
  include FastJsonapi::ObjectSerializer
  has_many :fighter_bouts, object_method_name: :ordered_fighter_bouts_api
  attributes :first_name, :last_name, :middle_name, :nickname, :nationality
end

Lastly, in our controller for this API endpoint (app/controllers/api/v1/fighters_controller.rb), we include the Fighter's association using its basic/underlying class name. And it understands to use the object_method_name that was given in the serializer:

class Api::V1::FightersController < Api::BaseController
  def show
    fighter = Fighter.api_find_by_id(params[:id])
    head(:not_found) and return unless fighter
    payload = ::V1::FighterSerializer.new(fighter, {include: [:fighter_bouts]}).serialized_json
    render json: payload
  end
end

Does this help you and answer the questions you had?

from fast_jsonapi.

krzkrzkrz avatar krzkrzkrz commented on July 17, 2024

Yeap that explanation makes sense. I see how it works now. Thank you for that

However, I think this doesnt help my case. What I need to do, is call object_method_name with an arg. i.e. ideally passing params to it, so I can filter against it

In your example. Would be good to be able to pass an arg to ordered_fighter_bouts_api. i.e. ordered_fighter_bouts_api('mma'). Which will give you the ability to return ordered fighter bouts by sport

from fast_jsonapi.

benlinton avatar benlinton commented on July 17, 2024

I didn't realize these take blocks. This is perfect, thank you!

from fast_jsonapi.

batshoes avatar batshoes commented on July 17, 2024

Hey guys, struggling with this. I feel like I'm following this advice, the object_method_name sounds like exactly what I want but I'm not getting the details I expect.

# lead_serializer.rb
class LeadSerializer
  include FastJsonapi::ObjectSerializer

  attributes :requested_amount, :loan_purpose ...

  has_many :products, object_method_name: :products_with_default
end

# lead.rb
class Lead < ApplicationRecord
...
  has_many :products, -> { unscope(:order).distinct },
           through: :matches, dependent: :nullify
...
  def products_with_default
    return products if products.present?
    Product.where("supported_loan_purposes ilike ?", "%#{loan_purpose}%")
  end
end

When I run these methods outside the serializer i.e.

$ Lead.first.products
=> []
$ Lead.first.products_with_default
=> 
[
  #<Product: 0x00007fdcbe33d810> {
    id: 1234
    ... 
  }
]

I get the expected outcome.
However my LeadSerializer is returning null for the products relationship

{
  :data => {
    :id            => "1234",
    :type          => :lead,
    :attributes    => {
      :requested_amount  => 10,
      :loan_purpose  => "general"
      ....
    },
    :relationships => {
      :account           => {
        :data => {
          :id   => "1234",
          :type => :account
        }
      },
      :products      => {
        :data => []
      }
    }
  }
}

Can someone point out what is going wrong with my configuration, or if there's a caveat I'm not aware of? Thank you!

EDIT: Perhaps is the issue the :through ?

from fast_jsonapi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.