I have a service that uses an ERB file to render a template form.
In the form I use several helpers, but they don't seem to be available in this context.
how could I use my helpers in the rendering via ERB.new(template).result(binding) ?
this is the error I'm getting:
*** NoMethodError Exception: undefined method `image_encoded' for #<MyService>
here's the call in the service app/services/my_service.rb file:
ERB.new(template).result(binding)
here's my helper app/helpers/my_helper.rb:
module MyHelper
def image_encoded(image_url)
<<image stuff>>
end
end
here's my call to the helper in the app/views/my_template/my_template.html.erb file:
<img src="<%= image_encoded(image) %>"/>
In your service your helpers are not included by default. You can include the methods from a particular helper like this:
class MyService
include MyHelper
end
Related
I have a PDF template and I need to use a view helper method inside a HTML file that is in the services folder to generate the PDF. However, when I try to use the default view helpers, I get an exception that the method doesn't exist.
ActionView::Template::Error: undefined method `helper_method' for #<#<Class:0x000000000e309bd0>:0x000000000e3a0350>
How can I make this work?
You can make your module methods work as they were class methods by using
module_function :method
The code looks like this:
module Helper
def helper_method; end
module_function :helper_method
end
Then in your html.erb you do this:
<% Helper.helper_method %>
I have a html.erb file used for an email template.
Is there any way to include a helper module and use it's methods within this file?
Something like:
a mails_helper.rb file:
module MailsHelper
def mail_to
"foo"
end
end
and in mail_template.html.erb:
<% include MailsHelper %>
<h2> This mail was sent to: <%= mail_to %> </h2>
Add helper :mail to the top of your ActionMailer derived classex:- app/mailers/mails_mailer.rb
class MailMailer < ActionMailer::Base
helper :mails
...
end
Checkout this answer
Name the helper file with same prefix as the ActionMailer's file name.
For example:
mailer: users_mailer.rb helper: users_mailer_helper.rb
According to the ruby on rails naming conventions - any view rendered by UsersMailer would have access to your helper methods.
I'm probably missing some things.
Say for example I have a helper function in app/helpers/foo_controller.rb and the code is as follows:
def sample_helper(count)
#implementaton...
end
and I want to use this helper in a webpage generated by rails and the code is as follows:
<%= sample_helper(user.id) %>
and if I try to run the webpage it will throw me an error saying that the method is not defined.
Thanks in advance!
You don't quite have the naming conventions right.
Name your helper file app/helpers/foo_helper.rb and in it you should have this:
module FooHelper
def sample_helper(count)
"#{count} items" # or whatever
end
end
And now, from any view rendered by FooController you should be able to use the sample_helper method.
Also, you should know that if you use the rails generators this structure is setup for you. All you need to do is add methods to the files that get generated. That way you don't need to guess the naming conventions.
For example, this command will make a controller file, controller test files, a helper file, and and an index view file, all ready for you to customize.
rails g controller foo index
Is your helper should be in a file called app/helpers/foo_helper.rb that contains a a module of the same name as the helper (camelized) Like:
module FooHelper
def sample_helper(cont)
# implementation
end
end
That's the way Rail auto loads helpers.
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.
I have Rails application with mounted Engine.
#{main_app}/config/routes.rb
mount CommentIt::Engine => "/talk", :as => 'comment_it'
And want to open engine views within main application layout.
#{main_app}/app/views/layouts/application.html.erb
<html>
<body>
<%= link_to "users", users_path %>
<%= yield %>
</body>
</html>
When accessing engine views(0.0.0.0:3000/talk) I got error 'undefined method `users_path' for #<#:0x007f9dbf0f7800>'
users_path works fine in main application views.
How I get route helpers from main application, when accessing Engine pages?
I'm not yet sure how (un)wise this might be, but have just found the following to work for a mountable/isolated engine I'm working on:
# in app/helpers/my_engine/application_helper.rb
module MyEngine
module ApplicationHelper
def method_missing(method, *args, &block)
main_app.send(method, *args, &block)
rescue NoMethodError
super
end
end
end
Thoughts?
As of Rails 3.2 the only way to do this is convert your engine into a 'full' engine and not a mountable engine. In mountable engines, the engine has no knowledge of the host application and its path/url helpers are not accessible by default.
This answer explains what needs to be done, which worked for me.
The alternative is to traverse the host application's files and include the proper view/application helpers into your engine. It works, but for me it was too much of a hassle. Simply converting to a full engine did the trick.
If you want to access engine helpers from the main application, you can use the name that you created for the app when you mounted it.
In config/routes.rb in your main application:
MyApplication::Application.routes.draw do
mount MyEngine::Engine => "/some_engine", :as => "some_engine"
get "/path_i_want_to_reference_from_main_app" => "some_controller#some_action"
end
Inside main application controllers/views:
some_engine.path_i_want_to_reference_from_main_app_path
So in your case you would use:
<%= link_to "users", comment_it.users_path %>
If you want to access main application helpers from an engine, try main_app.users_path
http://edgeapi.rubyonrails.org/classes/Rails/Engine.html
To access main app helpers (ApplicationHelper) from engine's views I tried include this:
app/helpers/your_engine/application_helper.rb
module YourEngine
module ApplicationHelper
include ActionView::Helpers::ApplicationHelper
end
end
It works, but once, when I restarted dev server, it throws me uninitialized constant ActionView::Helpers::ApplicationHelper, but I can't reproduce this exception.
EDIT
Removed this include and made this one:
lib/my_engine/engine.rb (it's inside engine)
module MyEngine
class Engine < ::Rails::Engine
isolate_namespace MyEngine
config.to_prepare do
ApplicationController.helper(ActionView::Helpers::ApplicationHelper)
end
end
end
In my case i had MyCustomEngineController inside my gem, which inherited ApplicationController, like so:
module MyEngine
class MyCustomEngineController < ApplicationController
#...
i changed this inheritance a little bit:
module MyEngine
class MyCustomEngineController < ::ApplicationController
#...
(notice :: before ApplicationController)
and now all my app's helpers are available for my engine's views