HTTParty default_params using a dynamic assigning method - ruby-on-rails

I am using the default_paramsto set a default argument to be appended to all REST calls.
But in my case i have the following:
default_params permanent_argument: self.calculate_permanent_argument
calculate_permanent_argument is a method calculating dynamically the permanent_argument.
Now the issue is that calculate_permanent_argument is called only once when the server restarts, and the value of permanent_argument never changes afterwards.
I want to be able to recalculate the permanent_argumenteach time i do a REST request while using the default_paramshelper.
Any clues?
Thanks!

You're using the class methods for default_params, so it will only be called once.
But there is corresponding instance method for default_params
I guess that you may create instance of your class for query, with it to call the instance method of default_params with self.calculate_permanent_argument
for example, at the controller inside your action method.
I'm just learning to use HTTParty, my guess may not be working.

Related

OGNL needs to call a method

I need to call a method from my action object inside the JSP, something like:
var currentStatus = ${getCurrentStatus()};
I cannot call an attribute, and I tried following this answer (How to call an action method using OGNL) and it didn't work.
There are a variety of ways to call methods (on actions, on other objects, or static methods from classes) from OGNL.
In this case, however, I don't see any issue with using a normal accessor. Note that the JavaBean convention is almost (completely?) about naming. A getter named getCurrentStatus(), accessed simply in OGNL via currentStatus, can contain whatever code you want.
This could include the DB access you mention in your question, etc.

call arbitrary chained methods on wrapper class

I'm creating a wrapper class for an API because my application will need to call it with different credentials at different times. I started off passing the wrapper a method and arguments and then doing (basically) this when calling it
call
set_credentials
TheAPI::Thing.send(method, args)
ensure
reset_credentials_to_default
end
HOWEVER, I realized that a challenge here is if I need to chain methods; this way I can only call one at a time; so for example I wouldn't be able to to TheAPI::Thing.find(id).delete. (At least, not without re-calling the credentials setter, which is undesirable since I have to fetch a token).
Is there a way using ruby to collect the methods/args being chained onto an object? Or would I simply have to pass in some ugly ordered set of things?
EDIT: Surely activerecord's query builder does something like this, collecting the chained methods before returning, and then after they're all collected, ensuring that as a final step the query is built, called, and returned?
the way to do this is to define a proxy object and to pass that around instead of the actual thing.
In the object itself, hold a reference to the Thing and override method_missing: http://ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing
In the method missing do the thing you are doing today. In a nutshell this is what ActiveRecord is doing.
As far as chaining things, I don't believe it would be a problem as methods that can be chained usually return references to self. When you call the 2nd method in the chain, you actually have done the work for the first one and have an object that has the 2nd method in the chain. The only trick you need to pay attention to is that you want to return a reference to the proxy class that encapsulates the thing instead of the actual return of the thing if you want the chaining to succeed.
Give it a shot and ping me if you run into trouble and I can spin up a fully working example.

Rails params "method" isn't a method, is it?

In the Rails documentation, the following example is given as a way to display what the server receives from a POST request:
def create
render plain: params[:article].inspect
end
In the subsequent description, the text states
The params method is the object which represents the parameters (or fields) coming in from the form. The params method returns an ActiveSupport::HashWithIndifferentAccess object.
While I understand that all methods are objects, I don't understand how it's correct to refer to the params object as a method. Specifically, the phrase "returns an ActiveSupport::HashWithIndifferentAccess object" suggests to me that there are two calls going on--what in python might look like:
params().__getitem__('article')
but I don't think that's what's actually going on.
The conversation around those lines also refers to params as a method, so I'm starting to think I must be missing something.
I'm new to Ruby, and while I understand that all methods are objects,
No, they aren't. Methods belong to objects (more precisely: methods are defined in modules, and executed in the context of objects), but they are not, by themselves, objects. (It is, however, possible to obtain a reflective proxy which represents the concept of a method by calling the method method, which returns a Method object.)
I don't understand how it's correct to refer to the params object as a method.
Because it is a method. Not an object.
What else would it be? Syntactically, it's obvious that it can only be one of three things: a keyword, a variable, or a method call.
It can't be a keyword, because Rails is just a Ruby library, and Ruby libraries can't change the syntax of the language (e.g. add or remove keywords). It can't be a variable, because in order for it to be parsed as a variable, the parser would need to have seen an assignment to it within the same block.
Ergo, the only thing it can possibly be, is a method call. You don't even need to know anything about Rails to know this. It's just basic Ruby syntax 101.
Specifically, the phrase "returns an ActiveSupport::HashWithIndifferentAccess object" suggests to me that there are two calls going on--what in python might look like:
params().__getitem__('article')
but I don't think that's what's actually going on.
That is exactly what is going on. You call the method params and then you call the method [] on the object that is returned by calling the method params.
This is in no way different from foo.bar: you call foo, then call bar on the return value of foo.
The params method is a method, returns a hash (which holds some details about parameters send to the app). Simplified it looks like this:
def fake_params
{ :controller => 'foo', :action => 'bar' }
end
You can call another method directly on the returned hash like this:
fake_params[:action] #=> 'bar'
params is a method defined in ActionController::Metal which returns the request.parameters object.
https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal.rb#L140

Explain the difference between ActionController#respond_to and ActionController::respond_to

I've read the documentation, and it confuses me every time, just because it doesn't answer some basic things. I realize the main purpose of the class method ::respond_to (which is normally used at the top of the controller) is for use in conjunction with respond_with. And the purpose of the instance method #respond_to (normally at the end of each action) is to provide different responses for different formats.
I also know that it's possible to consolidate the instance method version to look like the class method, but used inside an action, for conciseness, like this: respond_to(:html). The use case for this is another purpose of #respond_to, which is to refuse requests for unspecified formats. (I think it raises an UnspecifiedFormat exception)
Does the class method also have the same functionality? For instance, if I have a controller that only responds to html, if I just put respond_to(:html) at the top of the file, can I expect it to refuse requests for other formats? I've had problems with it doing that, so I don't know if I've been doing something wrong, or if it's just not supposed to work the same as the instance method in that respect.
So I finally ran an experiment, and no, the class method respond_to does NOT refuse requests to unspecified formats like the instance method does. Kind of a confusing disparity, but there you have it. If you want to refuse requests for invalid formats (with a 406), you have to specify valid formats inside each action of each controller (using the instance method respond_to)

Access session variable or controller variable from module

Using: Rails 3.0.3
I have this feature of my website (count calculate . com) which consists of plenty different calculations. The user can set his own variable for decimals (significant numbers) through a form. First I set this variable as a configatron variable which turned out to be a bad idea (a change that some user did was passed on to all users).
So, I decided to make it a session variable, which makes sense since a user should select his own decimal value.
Now, in the controller I call a module function that in turn calls 100 different module functions, depending on id.
My problem:
I want to access this session variable in that module which turns out to be impossible. Passing it already from the controller (through the model) is a bit of a nightmare since it needs to be passed for each and every function.
So:
How do I access session variables from a module in the lib-catalog?
How could I access a controller method from a module? If so I could call that method and fetch the session variable.
Do you mean a ruby module? As in a mixin? If you're including it in your controller, it already has access to everything the controller has access to. Just call session, request, params etc and all will just work.
If you really need to get the session from some arbitrary part of the system, you can obtain the request with:
ActionDispatch::Request.new(ENV)
Then you can get the session from the request. (Note that request is actually a singleton in disguise... it won't build a new request if one is already built).
Here is one way to do it, mix your calculation module into the controller
# application_controller contains a method that wraps your session value
class ApplicationController < ActionController::Base
protect_from_forgery
def user_value
return 5 # really a session value
end
end
The module that contains your calculation methods needs access to the session, since you are mixing it into the controller you can call the user_value method with self
module CalculationModule
def super_cool_calculation
return self.user_value * 420
end
# more calculation methods
end
note the self.user_value call, that method is not defined in the module but you will need to define it in the class you mixin to
class FooController < ApplicationController
include CalculationModule
def show
#calculation = super_cool_calculation # call calculation module method
end
# etc...
if any of your model objects also define a user_value method you could then mixin the calculation module to those if needed, they would probably not be getting the value from session
Something else to consider, just store the user defined value in the database instead of the session, you will have easy access to the value from the model or controller
it sounds like your Model is including the module code. You really really do not want to use or access the session directly from there. It breaks the purpose for MVC, Rails is doing its best to prevent you from trying something like that.
when you say " I call a module function that in turn calls 100 different module functions, depending on id." I would like to see that chunk of code.
Your original idea is the correct one...the value needs to be passed over to the model...it just sounds like the code needs to be DRY'd up a little so that it isn't such a headache.
It is hard to give recommendations without seeing the code. I was stuck in a similar situation and used dynamic methods (overriding method_missing) to get around the problem.

Resources