Putting instance method results (with arguments) into active_model_serializers - ruby

I'm making a JSON API and want to serialize a recipe record from my database. In the JSON response, I want to include the output of #recipe.is_favorited_by?(current_user) along with some of the recipe's attributes.
I saw from the docs that I could call: render json: #recipe, methods: :is_favorited_by? - but I'm not sure how to pass in current_user as an argument.
What call would I need to make in order to include the results of #recipe.is_favorited_by?(current_user) in the response?

You can add current_user attribute to your model & set it before your json execute.
See stackoverflow question link Ruby to_json :methods arguments

Related

Rails, rspec: using "send()" to dynamically generate capybara URLs for controller specs

Inside a controller spec for a #show action:
resource_name = "adoption_transfer_type"
it "returns a single resource" do
resource = create(resource_name.to_sym)
# Works
xhr :get, api_v1_lookups_adoption_transfer_type_path(resource.id)
# Does not work
xhr :get, send("api_v1_lookups_#{resource_name}_path(#{resource.id})")
end
It results in the following error:
Failure/Error: xhr :get, send("api_v1_lookups_adoption_transfer_type_path(#{resource.id})")
NoMethodError:
undefined method `api_v1_lookups_adoption_transfer_type_path(66)'
It looks like send(...) is converting it to a string literal instead of executing it as Ruby code, but I thought that was the purpose of the send(...) method.
The broader picture is I'm using a single spec file to generate the specs for several lookup resources, since they are all the same and there's no reason to manage 10+ files when I can do it all in one.
the string interpolates to api_v1_lookups_adoption_transfer_type_path(2) which means you're trying to call some method by that name. Instead you want:
send("api_v1_lookups_#{resource_name}_path", resource.id)
This is how you pass arguments to a send call, also i'd get into the habit of using public_send =)

How can request params be validated to ensure they include required params and don’t include unsupported params?

This is particularly in the context of a REST API built with Ruby and Sinatra.
It's easy enough to manually check to make sure that the required params are not nil. And it's easy to iterate through a flat params hash to see if it's allowed in a whitelist.
However, when the params hash also include hashes it becomes more difficult.
One way of handling this I've thought of is converting the params hash to JSON and using a library to validate it against a JSON schema.
I have come across the sinatra-param gem but I haven't had a chance to see if it can validate sub-hashes or check for unsupported params.
Edit: Another possible way, that might make more sense is passing params directly to the model (I'm using DataMapper) and using its validation and errors instead of rewriting validations.
If each of your routes are going to take the same 4 params (IE :one, :two, :three, :four), you could set up a before filter, store an array of those four params as an instance variable in the before (which is accessible to all routes) and use a sexy little method from class Enumerable called all?:
before do
#base_params = [params[:one], params[:two], params[:three], params[:four]]
unless #base_params.all?
redirect '/error_route'
end
end
Enumerable#all? will return true only if all values in your 'collection' are not false or nil. Documentation can be found here for Ruby 1.9
Additionally if you find that you have different sets of params, you can create a hash instead of just an array of #base_params where they keys are the string value of request.request_method:
before do
#base_params = {"GET" => [params[:one], params[:two], params[:three], params[:four]],
"POST" => [params[:five], params[:six], params[:seven]],
"PUT" => [params[:one], params[:five], params[:six]]}
unless #base_params[request.request_method].all?
redirect '/error_route'
end
end

Ruby WebMock: Getting Actual Parameters Passed Through a Method and Using Them in Spec File

I'm using WebMock to stub out HTTP requests. I have this one particular call where, instead of creating dummy data to pass through, I want to be able to capture the actual parameters I would pass into my send() method. Therefore, I need access to those actual parameters in my spec and I imagine I would need to somehow capture that context.
So, for example, in my application I'm calling this method:
send(method, uri, :body => data_file)
And in my spec file I'm stubbing the method:
FoobarModule.should_receive(:send).with(args)
Is there any way I could -- in WebMock, Rspec -- get the context of when send() is being called in the application and grab those parameters I'm passing through to use them within the spec and replace them with args?
I've looked through the documentation and I don't see much of anything on this. If there's anyone aware of this, I would greatly appreciate your help. Thanks.
Using WebMock you could use request callbacks to capture request data:
WebMock.allow_net_connect!
WebMock.after_request do |request_signature, response|
puts request_signature
end

Local variables in a block that are not passed as parameters [duplicate]

This question already has answers here:
Rails params explained?
(5 answers)
Closed 9 years ago.
I'm trying to understand how to make a variable available to a block that is not passed to the block as a parameter.
For example, how does Sinatra make params hash available?
get '/hello/:name' do
howAmIAccessingThis = params[:name]
end
Where is params coming from? This:
get '/hello/:name' do |params|
#hisName = params[:name]
end
might make sense because params is declared as a block argument, but that's not how it works. Looking through the source I cannot find how the params hash is getting passed to the block without it being a block parameter.
If it is not a local variable or a block variable, then it is a method. I don't know about Sinatra, but there must be a method params defined somewhere.
Using Parameters
Parameters in Sinatra are like everything else--simple and straightforward.
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
get '/hello/:name' do
"Hello #{params[:name]}!"
end
Once you've made this change, you'll need to restart the Sinatra application. Kill it with Ctrl-C and run it again. (There's a way around this, but we'll look at that in a future article.) Now, the parameters are straightforward. We've made an action called /hello/:name. This syntax is imitating what the URLs will look like, so go to http://localhost:4567/hello/Your Name to see it in action.
The /hello portion matches that portion of the URL from the request you made, and :name will absorb any other text you give it and put it in the params hash under the key :name. Parameters are just that easy. There is of course much more you can do with these, including regexp-based parameters, but this is all you'll need in almost every case.
Reference: http://ruby.about.com/od/sinatra/a/sinatra2.htm
EDIT
params values can come from the query string of a GET request, or the form data of a POST request, but there's also a third place they can come from: The path of the URL.
As you might know, Rails uses something called routes to direct requests to their corresponding controller actions. These routes may contain segments that are extracted from the URL and put into params. For example, if you have a route like this:
match 'products/:id', ...
Then a request to a URL like http://example.com/products/42 will set params[:id] to 42
So, whenever an URL GET, POST or Path contains such pattern then params hash is automatically constructed by rails.
Also check the Parameters section(Section 4) here

Sinatra, retrieve only post parameters

I know I can retrieve every parameter in Sinatra using "params".
However, How can I retrieve only post parameters? I need to verify that a parameter was sent by POST, otherwise it should be ignored.
Thanks.
Accessing the request object directly gives you a simple way of accessing post data, much like the php $_POST variable:
post '/' do
request.POST.inspect # instead of params.inspect
end
More info on the Rack request object here: http://rack.rubyforge.org/doc/classes/Rack/Request.html#M000274

Resources