How to find and use a helper method from String - ruby-on-rails

I would like to know how to find and use a helper method, when I have the name of the helper in a string format.
I am writing an engine, and in the initializer file, users can specify the current_user_helper as such:
MyEngine.current_user_helper = "current_user"
I would like to do something with this in the controller. For instance, the code below tries to create a Post for the logged in user.
MyEngine.current_user_helper.posts.new(post_params)
Yet, this code does not work because MyEngine.current_user_helper is a string. Apparently, Rails will throw an error when I try:
MyEngine.current_user_helper = current_user
without the quotation marks.
Any suggestions?

You can use send to call a method from a string or symbol. send is available on all descendants of Object.
send(MyEngine.current_user_helper).posts.new

Related

How to access params hash in lib directory rails 6

In my rails app, I am using Kramdown to parse Markdown. I want to extend the functionality of the convert_a method in the HTML converter. Part of this involves accessing the database, but it is dependent on a parameter in the URL. Because I am not directly calling the method that I am overriding I cannot simply pass the method the params hash. Is there a way to access this hash, or even just get the current URL in a module in the lib directory?
to give a bit more context, the method call is in a helper method here:
# in app/helpers/myhelper.rb
def to_html(text)
Kramdown::Document.new(text, parse_block_html: true).to_custom_html
end
and here is the file in which I override the convert_a:
# in lib/custom_html.rb
class CustomHtml < Kramdown::Converter::Html
def convert_a(el, indent)
# use params[:foo] to make query
format_as_span_html(el.type, el.attr, inner(el, indent))
end
end
Edit:
To give a bit more context on where the overrided method is called. I am not extremely familiar with the Kramdown codebase, however it seems that when to_custom_html is called the following bit of code is run inside of Kramdown.rb:
output, warnings = Converter.const_get(name).convert(#root, #options)
which subsequently calls convert_#{el.type} on the internal kramdown elements.
You can pass additional options in Kramdown::Document#new, so just do something like Kramdown::Document.new(text, my_params: params). Then you can use the #options method of the converter to access your params.

passing named_scope as argument

I am reusing a controller method and I need to change the scope as required.
I have stored the scope name in a session and would like to be able to do the following.
if params[:scope_name]
session[:submission_scope_name] = params[:scope_name]
else
session[:submission_scope_name] = "allSubs"
end
#search = Submission.session[:submission_scope_name].search do
...
end
The code above is giving me the following error message:
undefined method `session' for #<Class:0x00000002ad7df0>
Is there any way of passing a named_scope as an argument?
You probably don't want to do this from a security standpoint: a malicious user could make a poorly-formed submission_scope that you'll just be sending straight to Submission.
That said, you're looking for the method send here. Try this instead:
Submission.send(session[:submission_scope_name].to_sym).search
send will try to call a method on that object named whatever symbol you passed in. You can read more about it in the Ruby core docs, but ultimately doing that would allow you to send whatever named scopes to Submission you want.

rails passing parameter from view to a different controller as a string

Im trying to pass a parameter (a file path : eg. user/lauren/tools/) from a view in RAILS to another different controller using RUBY. I want to use the file path (as a string) to be matched with a regular expression. To do that, right now Im using the params [:parameter] method as follows in the controller action where Im setting the variable instance:
#variable = /^.+\/[^\/]+$/.match(params[:name]).to_s ---where :name is the parameter passed from view
Right now, I dont get any output when I try to display that in the corresponding view of that controller....im guessing its the params [:name] method I need to replace or modify?
Id really appreciate views on this...thanks!
While your server is running open a new terminal window and type rails console. This will let you see what your variables actually contain. You can type params and see what the hash has in it and see why your regex is failing. It sounds to me like you are trying to match your path, not your params.

Using parameter[:user_id] ,params[:user_id], params["userid"] in Rails?

While studying a Rails application I saw statements like:
parameter[:user_id]
params[:user_id]
params["userid"]
Can anyone tell me if there any major difference between them? Or, are all
fetching parameters only and can I use them interchangeably?
parameter[:user_id]
I don't think this is something official. However there's a parameters method on the current request object. See request.parameters in a controller action.
params[:user_id]
Using the params[:user_id] is the same as calling request.parameters[:user_id]. Also params[:user_id] is the same as params["user_id"]. See HashWithIndifferentAccess.
I am not sure if that's just a typo on your part, but params[:user_id] and params["userid"] are not the same, even with HashWithIndifferentAccess. The _ won't just go away so they can hold different values.
No, you need to look at the context in which each one is used. params is the normal parameter hash made available to methods in your controllers. It contains the parameters passed in as part of the request as GET or POST params.
So, given the following URL:
http://www.testsite.org/some_resource?user_id=13
The params[:user_id] would contain the value 13.
If the URL instead was:
http://www.testsite.org/some_resource?userid=13
You would need to use params[:userid] to get the value. So it all comes down to the way the URLs are made for the different controllers.
There's a third way, where you can map parts of the URL itself to params in the routes into your application. See config/routes.rb in your application. For instance with the following route:
match '/user/:user_id' => 'users#show'
You could pass in an URL like this:
http://www.testsite.org/user/13
And in your UsersController.show method you could access the user id by using params[:user_id] like normal.
The parameter hash is most likely a local copy of or reference to the params hash in a helper method or something.
params and parameters are the same. They return both GET and POST parameters in a single hash.
There is no such a thing as parameter.
ref: rails api

Rails passing message to dynamic method

So I want to dynamically have new_course_discussion_path(#discussable) or new_group_discussion_path(#discussable) depending on the #discussable class type. How do I pass the message (#discussable) in to this method? I tried:
"new_#{#discussable.class.to_s.downcase}_discussion_path".constantize(#discussable)
but this says "wrong number of arguments (1 for 0)". I'm new to rails. Please help! Thanks.
Update:
Right now, the whole line is
= link_to '>New Discussion', "new_#{#discussable.class.to_s.downcase}_discussion_path".constantize(#discussable)
send "new_#{#discussable.class.to_s.downcase}_discussion_path", #discussable
The path helpers are methods not classes. They're accessible from controllers, views and helper methods and if you don't qualify the send call, it will invoke the method on self.
You are looking for the Object.send method.

Resources