Why isn't my rails 4 helper working? - ruby-on-rails

I have a helper module for my home page with two methods that do the same thing:
module HomeHelper
def parsed_text(tweet)
auto_link (tweet).gsub(/(#\w+)/, %Q{\\1})
end
def other_parsed_text
self.auto_link.gsub(/(#\w+)/, %Q{\\1})
end
end
In my view this works:
<%= parsed_text(tweet.text) %>
But this doesn't:
<%= tweet.text.other_parsed_text %>
I get a NoMethodError at /
undefined method other_parsed_text. Isn't self the caller of the method inside of my helper method?
What am I doing wrong? I want the second style of calling methods with a . notation to work too. How do I do that?

This does not work because you didnt extend the class that tweet.text is of. You can use ActiveSupport::Concern if you want to extend some class. What you are doing now is provding some methods that can be called with parameters.
// I posted an example here: https://stackoverflow.com/a/8504448/1001324

Related

Are application helper methods available to all views?

Rails 4.1
Ruby 2.0
Windows 8.1
In my helpers/application_helper.rb, I have:
def agents_and_ids_generator
agents = Agent.all.order(:last)
if agents
agents_and_ids = [['','']]
agents.each do |l|
name = "#{l.first} #{l.last}"
agents_and_ids << [name,l.id]
end
return agents_and_ids
end
end
In my views/agents/form.html.erb, I have the following:
<%= f.select :agent_id, options_for_select(agents_and_ids_generator) %>
In my controllers/agents_controller.rb, I have the following:
include ApplicationHelper
But when I go to this view, I get the following error message:
undefined local variable or method `agents_and_ids_generator' for #<#:0x00000006fc9148>
If I move the agents_and_ids_generator method to the helpers/agents_helper.rb, it works fine.
I thought that by putting methods in the application helper and including the application in a controller, then these methods are available to the views. Am I incorrect in that assumption?
Answer:
Making sure that application helper is not included in controllers, and added the following simplification:
<%= f.collection_select :agent_id, Agent.all.order(:last), :id, :name_with_initial, prompt: true %>
#app/models/agent.rb
Class Agent < ActiveRecord::Base
def name_with_initial
"#{self.first} #{self.last}"
end
end
Helpers
The bottom line answer is the application_helper is available in all your views.
Rails actually uses helpers all over the place - in everything from the likes of form_for to other built-in Rails methods.
As Rails is basically just a series of classes & modules, the helpers are loaded when your views are rendered, allowing you to call them whenever you need. Controllers are processed much earlier in the stack, and thus you have to explicitly include the helpers you need in them
Important - you don't need to include the ApplicationHelper in your ApplicationController. It should just work
Your Issue
There may be several potentialities causing the problem; I have two ideas for you:
Is your AgentsController inheriting from ApplicationController?
Perhaps your inclusion of ApplicationHelper is causing an issue
Its strange that your AgentsHelper works, and ApplicationHelper does not. One way to explain this would be that Rails will load a helper depending on the controller which is being operated, meaning if you don't inherit from ApplicationController, the ApplicationHelper won't be called.
You'll need to test with this:
#app/controllers/application_controller.rb
Class AgentsController < ApplicationController
...
end
Next, you need to get rid of the include ApplicationHelper in your controller. This only makes the helper available for that class (the controller), and will not have any bearing on your view
Having said this, it may be causing a problem with your view loading the ApplicationHelper - meaning you should definitely test removing it from your ApplicationController
Method
Finally, your method could be simplified massively, using collection_select:
<%= f.collection_select :agent_id, Agent.all.order(:last), :id, :name_with_initial, prompt: true %>
#app/models/agent.rb
Class Agent < ActiveRecord::Base
def name_with_initial
"#{l.first} #{l.last}"
end
end
Rails 5 update. I ran into a similar issue with views not picking up a method from application_helper.rb. This post helped me. The files that are provided in the helpers directory of a new rails app are for those views only. Methods in the application_helper.rb will not be available automatically to all views. To create a helper method that is available to all views, create a new helper file in the helper directory such as clean_emails_helper.rb and add your custom method here like this:
Module CleanEmailsHelper
def clean_email(email)
*do some stuff to email*
return email
end
end
Then you can call <%= clean_email(email) %> from any view in your app.

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

Rails with Cells and Helpers

I'm having trouble accessing the cookies object in my cell views via helper. My code looks like this:
#cell
helper SessionsHelper
#cell view
signed_in?
#sessions helper
signed_in?
cookies.sth
end
I'm getting the error: undefined local variable or methodcookies'`.
How do I make cookies visible there?
Alternatively, I'd like to pass Helper as an object collaborator to my cell, because this helper contains a lot of useful methods. Is doing SessionHelper.new the correct way to do that?
<%= render_cell :my_cell, :display, session_helper: SessionsHelper.new %>
I now see that SessionsHelper is in fact a module, so I cannot invoke the new() method. What should I do with undefined cookies?
I always define signed_in? in ApplicationController. (There cookies is available) And then do:
helper_method :signed_in?
to make it available as a helper method.
As for your second question: session_helper: SessionsHelper.new is not necessary. All methods from all helpers are available all views.

Rails: method defined in application_helper.rb not recognized by categories_controller.rb

More newbie issues.
I understand that if I define a method in my application helper, it is available to the entire app code.
In my applicaton helper, I have:
def primary_user_is_admin
if current_user
user_login_roles = JSON.parse(current_user.role)
if user_login_roles["admin"]
return 1
end
end
return nil
end
If I call it from the categories_controller:
if !primary_user_is_admin
redirect_to root_url
end
I get an error message: undefined local variable or method `primary_user_is_admin'
This also happens if I put the primary_user_is_admin code in the registrations_helper.rb file
However, if I use it in any of the views (views/user/edit.html.erb for instance)
<% if primary_user_is_admin %>
<% end >
then it works. What am I missing?
Helpers are not included into a controller by default. You can
include ApplicationHelper
To gain access to the methods in the ApplicationHelper module. The previous discussion has a bunch of useful solutions for accessing helpers in controller.
Methods defined in helpers are only available to views by default. You have to 'include ApplicationHelper' in the applications controller to get access to this method in the controllers.

How do I call a Rails helper method from inside another helper method?

I am writing a helper that needs to call another helper, which generates html. How do I do that?
try:
include AnotherHelper
Just call it.
If it is in a different helper file, your controller can include the other helpfile by using the controller method "helper"
Added:
Here is an example:
# in the view
<%= my_helper %>
# in the helper file
def my_helper
"<div>" + someother_helper_which_generates_html + "</div>"
end
** Please add more details to your question if this isn't helping....
Something like this should help you (say, in application_helper.rb)
module ApplicationHelper
def create_div
html("this is some content")
end
def html(content)
"<div>#{content}</div>"
end
end
In this case, the create_div method is calling the html method with a string as an argument. the html method returns a string of HTML with the argument you supply embedded. in a view, it would look like:
<%= create_div %>
hope this helps!

Resources