Closed mustela closed 8 years ago
The approach above looks like it would work, is there an error?
Yes, the error (one of it) is that you can't use it with several calls like
Configuration.dynamic_id = 1234
Person.all
Configuration.dynamic_id = 456
Person.all
Person.find(888)
The last line would use the second configuration, but how do I do if I want to use the first one?
OK, I get you. Unfortunately, it's really not built around the concept of having a client object.
I can't think of an easy way around this either. What is this used for? If it's literally "the logged in user", then it wouldn't be changing within a request. Can you give me a real world use case so I can try to understand the need a bit better and maybe help with an idea.
Sure, actually using the filter maybe isn't the best example, because as you are saying, it won't change per request.
I'm working on a rb client for this api, as you can see all of the resources started with /merchants/{id}/[something]
And for authentication you have to send a key with a token.
I have several merchants and I need to be able to use the same model structure for all of them, at the same time. Like I explained above.
Make sense? I love this library so hope we can find a workaround for it.
OK, so the easiest solution is probably something like:
class Person < ActiveRestClient::Base
base_url "https://myapi.com/resource/:merchant_id"
get :all, "/something"
end
Person.all(merchant_id: 1234)
Person.all(merchant_id: 555)
So you pass the merchant_id through on each call. It seems strange that you're going to be changing the merchant ID mid-request, but that's probably the best way - be explicit.
Failing that, you could create a wrapper client class.
class MerchantizedApi
def initialize(merchant_id)
@merchant_id = merchant_id
end
def method_missing(name, *args)
# Split name in to class and method
# Find the last args that is a hash (or add one if there isn't)
# set the :merchant_id field in that hash to @merchant_id
# Use class_name.constantize.send(method, args)
end
end
@merchant = MerchantizedApi.new(1234)
@merchant.person_find
It's a bit icky, but something like that may work.
First of all, thanks for spending the time to help me ;), and yes, your second approach could work, since I don't want to pass around the merchant id all over the code.
Also I was checking something like the following could work too:
class Client
def initialize(merchant_id)
build_client merchant_id
end
def build_client(merchant_id)
model = Class.new(Person) do
base_url "https://myapi.com/resource/#{merchant_id}"
end
self.class.send(:define_method, :person, -> { model })
end
end
So I could do
client = Client.new(1234)
client.person.all
client2 = Client.new(456)
client2.person.all
It's a great plan, but even better may be something like this (so you can pass in a list of classes you want to wrap):
class Client
def initialize(merchant_id, *classes)
build_client merchant_id, classes
end
def build_client(merchant_id, classes)
classes.each do |klass|
model = Class.new(klass) do
base_url "https://myapi.com/resource/#{merchant_id}"
end
self.class.send(:define_method, klass.name.underscore, -> { model })
end
end
end
client = Client.new(1234, Person, Task, Project)
client.person.find(1)
client.task.all
Yeah, def, was just showing you my point, but yes. I just did that but instead I used a constant to keep all my clases since they won't change.
Thanks a lot!!
Following this issue, I'm looking for a way to have the same model but with different credentials/header.
This is just to demonstrate the expected behavior the
It would be solved if the concept of a
client
would exist in the lib, so I could do something likeclient.person.all
and keep the configuration in the client. But haven't found a way to do it yet...Any idea how could I achieve this approach?
Thanks a lot!