Helper method with the same name as partial - ruby-on-rails

I have a helper with a method named search_form like this:
module Admin::BaseHelper
def search_form(*args)
# my great code here
end
end
To call this method in my HAML code, I can do this:
= search_form
= search_form()
= search_form(param1: "value1", param2: "value2"...)
My problem is with this first call. When I do this in any HAML file, it renders my helper. Except if my file name is _search_form.html.haml. Is that case, it returns nil.
If I put a raise error in the helper, I notice that my method isn't being called, but I am not able to find what is being called and why.
If I use the syntax on the second and third lines, it works as expected by calling my helper method.
So my question is: is this standard Rails behavior or a bug?

By default, Rails will look for a local variable with the same name as your partial, which may conflict with existing method names.
One way to get around this is to simply redefine the method inside your partial:
<% search_form = self.search_form %>
# Rest of the partial's code

Related

Calling method with argument in erb file Rails

I have erb file with passing object post
<%= getTime(post) %>
And I have conroller for this erb file
helper_method :getTime
def getTime (post)
end
But controller doesn't see passed argument.
getTime(post)
should be in a helper file.
Write this in application helper and it will be accesible in your view.
def getTime (post)
end
First of all remove the space between the method and the () in the def:
def getTime(post)
It probably is seeing the argument, since if it didn't it would throw an error saying you didn't supply it.
Whatever you're doing to "verify" that the argument is "seen" is probably not accurate.

need to pass parameter from controller to .html.erb file

My controller code:
def description
product = #products.find(params(:id))
end
This is in the controller and I have to pass the product variable to description.html.erb. How can I do this?
It is giving me an ArgumentError in StoreController#description.
In general the way variables from the controller get passed to the views is by assigning them as an instance variable, which are variables defined with an # before it, e.g #products. If you want the product variable to be passed along, it has to be set as #product, like so:
#product = #products.find ...
In this particular case, you are getting an error raised before your view even is called. The only line in your controller action is throwing this.
Make sure that #products is actually being set. It's not being set in the #description method, so is it being set in a before_filter here? Is #products able to call #find? In Rails we often only see a model calling this method, e.g Product.find(params[:id]).
Further more, I see that you're accessing your params hash with regular brackets instead of square brackets. In Ruby you use square brackets. This alone may be what's causing the error. Try changing that to:
#product = #products.find(params[:id])
You can pass variables from controller to views using #
example in controller :
#my_var = 'toto'
in view
<%= #my_var %>

Rails returning full object instead of integer

Rails's pluralize method was not working like I wanted (words not in english) so I set out to try my own solution. I started out simple with this method in ApplicationController:
def inflect(number, word)
if number.to_i > 1
word = word + "s"
end
return "#{number} #{word}"
end
And called it as such in my view:
<% #articles.each do |article| %>
<%= inflect(article.word_count, "word") %>
<%= inflect(article.paragraph_count, "paragraph") %>
...
<% end %>
But this got me:
undefined method `inflect' for #<#<Class:0x3ea79f8>:0x3b07498>
I found it weird that it referenced a full-fledged object when I thought it was supposed to be just an integer, so I tested it on the console:
article = Article.first
=> (object hash)
article.word_count
=> 10
article.word_count.is_a?(Integer)
=> true
So I threw in a quick words = article.word_count.to_i, but it doesn't throw a TypeError, it actually doesn't do anything, and still returns the same error: undefined method ``inflect' for #<#<Class:0x3ea79f8>:0x3b07498> in reference to the `inflect(article.word_count, "word") line.
Then I thought maybe inflect was already a Rails method and it was some sort of naming conflict, but doesn't matter what I change the method's name to, it keeps giving me the same error: undefined method ``whatever' for #<#<Class:0x3ea79f8>:0x3b07498>
I then tested it on the console and it worked fine. What's going on?
Put your inflect method in ApplicationHelper, not ApplicationController
by default all code in your helpers are mixed into the views
the view is its own entity, it is not part of the controller, when a view instance gets created (automatically when your controller action executes) it gets passed any instance variables you define in your controller action, but does not have access to controller methods directly
NOTE: you can define methods in your controller to expose them to your views by using the helper_method macro - see this post for more info on that - Controller helper_method
but in general you would define the view helper methods in the helpers classes and not in the controller

ruby on rails use variable in association call

i have a helper function which renders a partial and i pass a variable called method with it into the view...
when in view i use
<%= friend.method.profile.picture %>
the method variable can be either user or friend
and i get
wrong number of arguments(0 for 1)
i suppose there is a problem how i use the variable being passed into the association call... maybe i have to escape it somehow?
If I understand what you want, you are trying to dynamically call a function based on the value of a string argument called 'method'. Also, 'method' is an existing function in Ruby, (hence your error message about 'wrong number of args' vs 'undefined method'), so I would recommend renaming it in your code.
TLDR:
Rename your variable something like "person" (instead of 'method'), then
try some meta-programming to call the function using send:
friend.send(person).profile.picture
Here is the same answer as ~AmirRubin, but fleshed out more.
I am assuming that friend was the object, method was the helper, .profile is the method you want the helper to use.
Define your helper as:
def call_method(object, method_name)
object.send(method_name)
end
In your view call it as:
<%= call_method(friend, :profile).picture %>
Adjust this if my assumptions are wrong. If you need to send the method name (symbol) to the partial pass it in the locals.

Using rails helper method

I've found a helper method that I would like to use to resize embedded videos on my site. I've tried using this method several ways but received multiple undefined method errors. Here's the method:
def resize_video(new_width,new_height)
width,height = embed_code.match(/width=.?(\d+).*height=.?(\d+)/).to_a.drop(1)
embed_code.gsub(width,new_width).gsub(height,new_height)
end
I would like to apply this method to the <%= raw link.embed_code %> portion of my view, available HERE, to change the width and height to the desired values. Where should I put the method and how should it be called?
Update
Per Karel's advice, I put the method in links_helper.rb and used <%= raw (link.embed_code).resize_video %> in the view but received this error undefined method resize_video for #<String:0x492bf40>
I would suggest you to put the helper method in the corresponding helper of the view(ie. if the view file belongs a controller xyz, there should be a helper with name xyz_helper). This is the rails convention. If the helper method is used in multiple controller views, we can put it in application_helper.
If you are getting undefined method for embed_code, we have to pass that variable as follows
<%= raw resize_video(link.embed_code, width, height) %>
def resize_video(embed_code, new_width, new_height)
width,height = embed_code.match(/width=.?(\d+).*height=.?(\d+)/).to_a.drop(1)
embed_code.gsub(width,new_width).gsub(height,new_height)
end
Place your helper methods in a file name video_helper.rb in helpers folder. More here.

Resources