Ruby on rails accessing content of params hash in application controller - ruby-on-rails

I am trying to access the values stored in params hash from ApplicationController class directly.How can I do it? Foreaxmple:
def setParams
#parameters=params ???
end

The univesal variable to get the ruby params is:
params
This will return the hash of parameters from the request that you can see in the server log.
To access it you just need to use:
def set_params #use ruby notation for methods which is underscore and _
#parameters=params["key"]
end
Note that the key should be defined, as long as the incoming parameters for html view includes the codification: utf8, and the csrf token.
If you want to access to the full request:
def set_params
#request = request
end

class ApplicationController < ActionController::Base
before_filter :handle_params
def handle_params
my_param_key = params[:my_param_key]
end
end
Hope this helps someone starting to code on ruby!

Related

Adding Logstasher custom fields in ApplicationController

I am trying to log additional custom fields using Logstasher gem.
I need to log some response parameters, but logstasher does not support itself logging response params using configuration, therefore I put the code into after_action method in ApplicationController.
ApplicationController
after_action :set_logstasher_params
def set_logstasher_params
if LogStasher.enabled?
res_params = JSON.parse(response.body.as_json)
LogStasher.add_custom_fields do |fields|
fields[:res_params] = res_params
end
end
end
This is logstasher initializer
initializer/logstasher.rb
if LogStasher.enabled?
LogStasher.add_custom_fields do |fields|
fields[:request_params] = request.filtered_parameters
LogStasher::CustomFields.add(:myapi_runtime)
end
LogStasher.add_custom_fields_to_request_context do |fields|
fields[:request_params] = request.filtered_parameters
end
end
The problem is next:
After starting rails server, first request I send, logs only parameters which are indicated in logstasher.rb except parameters added in ApplicationController.
But After that every request logs everything indicated logstasher.rb as well as ApplicationController method.
Does anyone have idea why first time does not log response parameters from ApplicationController method?

Ruby on Rails variable visibility

I have many controllers where I set variables so that the appropriate views gain visibility to these variables. For example,
class UsersController < ApplicationController
...
def index
#users = User.all
end
...
This works. So how come this doesn't work:
class PlacesController < ApplicationController
...
def show
#params = params
end
...
If I byebug in the show-method, I can access params. If I byebug in the view (places/show.html.erb), then "params" and "#params" return nil.
Does this have something to do with the fact that "User" is an ActiveRecord and "Place" is not? How can I make arbitrary data accessible to the view?
You can use your controller instance variable #params in your /places views. But because you did not pass any params, params returns nil.
So, if this variables was out visibility, you would get NameError.
Try to set #params directly like #params = { foo: "bar" } and you will see it.
More about params in Rails here (#4 Parameters).

Disable strong parameters for a specific action

I have a serious problem with strong parameters. Its working pretty well in my about 200 actions but in one it doesn't because I'm working very dynamic with the parameters there and I also cant change it because of the applications design.
So I want to disable strong parameters validation in just this specific action. Is there a way to do this?
Strong parameters overrides the params method in ActionController::Base. You can simply override it and set it back to what you want yourself.
So this:
class MyController < ApplicationController
def params
request.parameters
end
end
Will effectively disable strong parameters for all actions in your controller. You only wanted to disable it for a particular action though so you could do that with:
class MyController < ApplicationController
before_action :use_unsafe_params, only: [:particular_action]
def params
#_dangerous_params || super
end
def particular_action
# My params is unsafe
end
def normal_action
# my params is safe
end
private
def use_unsafe_params
#_dangerous_params = request.parameters
end
end
Not too sure if this is best practice but for Rails 5 I just use request.params instead of params anytime I want to skip strong params.
So instead of something like:
post = Post.new(params[:post])
I use:
post = Post.new(request.params[:post])
You can use .permit! to whitelist any keys in a hash.
params.require(:something).permit!
However this should be treated as an extreme code smell and a security risk.
Nested hashes can be whitelisted with this trick:
params.require(:product).permit(:name, data: params[:product][:data].try(:keys))

How would I access url parameters in Mailer Preview

I have the following working Preview class:
class UserMailerPreview < ActionMailer::Preview
def invite
USerMailer.invite
end
end
I'm trying to pass paramaters to the method like so:
localhost:3000/rails/mailers/user_mailer/invite?key1=some_value
The server seems to receive them:
Parameters: {"key1"=>"some_value", "path"=>"user_mailer/invite"}
But when trying to access them with the hash params, I get an error.
Can I access these parameters in a Preview method and if so - how?
I dug into the code behind the mailer preview system and discovered that, unfortunately, none of the request parameters are passed to the preview class, and are thus inaccessible to the preview.
The relevant controller action is in railties: Rails::MailersControlller#preview. Here, you can see it calling ActionMailer::Preview#call and just passing the name of the "email" (ie: the appropriate method in the preview).
I hacked my way through this one today and came up with this solution and blog post on extending ActionMailer.
# config/initializers/mailer_injection.rb
# This allows `request` to be accessed from ActionMailer Previews
# And #request to be accessed from rendered view templates
# Easy to inject any other variables like current_user here as well
module MailerInjection
def inject(hash)
hash.keys.each do |key|
define_method key.to_sym do
eval " ##{key} = hash[key] "
end
end
end
end
class ActionMailer::Preview
extend MailerInjection
end
class ActionMailer::Base
extend MailerInjection
end
class ActionController::Base
before_filter :inject_request
def inject_request
ActionMailer::Preview.inject({ request: request })
ActionMailer::Base.inject({ request: request })
end
end

How to minify JSON output in Rails?

I am using .json.erb views instead of calling to_json method.
I've found several advices concerning JSON output minification. Ones tell about zipping all the output of web application, others recommend to use after filter or before render but they do not explain how to shrink spaces and tabs between JSON elements and where to take JSON input from and where to put the minified result. The third advices tell strictly about minifying JavaScript.
The easiest way is just to get Ruby to parse the whole response and spit it back out again using an after_filter. Try the following code in app/controllers/application_controller.rb.
class ApplicationController < ActionController::Base
after_filter :minify_json
private
def minify_json
response.body = JSON.parse(response.body).to_json if request.format.json?
end
end
If you decide that you want the JSON beautified instead of minified, you can use this code:
class ApplicationController < ActionController::Base
after_filter :beautify_json
private
def beautify_json
response.body = JSON.pretty_generate(JSON.parse(response.body)) if request.format.json?
end
end
Or, you could allow the requester to specify using a parameter:
class ApplicationController < ActionController::Base
after_filter :format_json
private
def format_json
if request.format.json?
json = JSON.parse(response.body)
response.body = params[:pretty] ? JSON.pretty_generate(json) : json.to_json
end
end
end

Resources