Skip to content

Conversation

v2kovac
Copy link

@v2kovac v2kovac commented Jan 9, 2024

Suggested change:

I only wanted this for graphql, but i added to either use case, I can change it to be more limited if you want.

From the graphql spec, this change enables something like this:

  def user
    BatchLoader::GraphQL.for(object.user_id).batch(default_value: nil) do |user_ids, loader|
      User.where(id: user_ids).each { |user| loader.call(user.id, user) }
    end
  end

  def user_id
    user.then(&:id)
  end

  def user_name
    user.then(&:name)
  end

Why do we need this?
Anytime I want to re-use a batch loader in graphql I have to make it a new nested graphql type within the type i'm working, you can't use the same loader across fields. Although in this case User should be a nested type, more generally there are cases where you want a flatter structure. This change really makes this repo feature parity with the "promise" implementations that allow you to manipulate the promises after they're fulfilled, this is very frequently used with these other repos where people refer to the same batch loader to extract different pieces of info from the same underlying model wherever they want, the batch loader shouldn't determine how we use it in graphql.

@exAspArk
Copy link
Owner

Thank you for submitting it, Vlad! 🙌

To be honest, I don't like using "promises" in Ruby and find the code confusing when I see .then since it's not an asynchronous execution. Do you think it's possible to achieve the same by designing an API that looks similar to Ruby's Lazy? Or the implementation will be too rough?

For example:

def user_id
  user.lazy.id
end

@v2kovac
Copy link
Author

v2kovac commented Feb 21, 2024

Thank you for submitting it, Vlad! 🙌

To be honest, I don't like using "promises" in Ruby and find the code confusing when I see .then since it's not an asynchronous execution. Do you think it's possible to achieve the same by designing an API that looks similar to Ruby's Lazy? Or the implementation will be too rough?

For example:

def user_id
  user.lazy.id
end

Yes I think that's doable, I'll take another crack at it, I knew you'd have a problem with then (it's also reserved for other things on ruby objects) but wanted to make sure this is a feature you'd even consider before I got into aesthetics 👍

@v2kovac v2kovac closed this Mar 29, 2024
@v2kovac v2kovac deleted the master branch March 29, 2024 18:30
@v2kovac v2kovac mentioned this pull request Mar 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants