Redmine-PlugIn development: helper method not found in view - ruby-on-rails

I'm writing a plugin for redmine and there is one thing i just don't get:
I have a helpermodule called approvals_helper.rb which contains a method 'rev_approved?'
module ApprovalsHelper
def rev_approved?(repository, revision)
# return some boolean value
end
end
Now i want to use this method in my view which is a partial and is called _approved.html.erb
<% if rev_approved?(#repository, #revision) %>
<p>show something</p>
<% end %>
This partial is rendered in the revision.html.erb (from redmine view/repositories)
But when i do i get this error message:
ActionView::Template::Error (undefined method `rev_approved?' for #<#<Class:0x7f801e6bf030>:0x7f801e669ae0>)
When i add "include ApprovalsHelper" directly to the ApplicationHelper it all works fine, but i don't want to change the code directly. Is there a way to do this in a my plugin?
Is this because i actually render my partial in the revision view? How can I get this to work?
I'm using redmine 2.3.1 , ruby 1.8.7 and rails 3.2.13
Many thanks!

in your init.rb add
require_dependency 'name_of_helper'

Related

Rails 5: Interpolated Single Quote Rendered As Unicode

Ruby version: 2.3.1
Rails version: 5.0.5
I am using Google's dataLayer to record ecommerce events in my site. We are in the middle of an upgrade from rails 4 to 5 and I'm running into a wall with one of my rails helpers. I use a helper to generate a product_list and inject it into the view so I can send it to the dataLayer.
In rails 4 the dom reflects what I write in the helper, including the quotes I need to include for the format. In rails 5 however, the quotes are being converted to unicode and I can't figure out why or how to avoid this. This is not happening when I bind on the method in the terminal, it's only happening when it is loaded in the dom. I've tried adding sanitize(), .html_safe, converting this to a hash and converting this to JSON and nothing is working.
Right now it is working on rails 4 like this:
def foo
result += "'var1':'#{item.id}',
'var2':'#{item.title}',
'var3':#{item.price}},{"
result
end
end
What I get in the DOM:
'products': [{
'var1':'result1',
'var2':'result2',
'var3': 'result3'
}]
What is being returned on the DOM in rails 5:
'products': [{
'var1':'result1',
'var2':'result2',
'var3': 'result3'
}]
Not sure where you called html_safe, I quickly added this to a view I had in Rails 5 to attempt to replicate and here are my results:
View Helper
module HomeHelper
def result
"{'var1':'test'}".html_safe
end
end
View
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= result %>
Generated Page
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
{'var1':'test'}

Ruby rails not creating instance variables

I am using a lynda.com tutorial for Ruby on Rails. The very first instance of creating and using array instance variables does not work. At first I thought it was that #array might have become a reserve word in the newer 5.0 version of rails that I am using, but changing it did not cause the "nil" (undefined) error to go away.
What is wrong with Ruby Rails 5.0? It is refusing to define instance variables and to pass them to the appropriate template.
This is extremely aggravating, since rails is not behaving as documented (i.e. RAILS IS BRAIN DEAD OUT OF THE BOX).
****************
demo_controller.rb
class DemoController < ApplicationController
def index
render('hello')
end
def hello
#zarray = [1,2,3,4,5] <------------ this is defined
end
def other_hello
render(:text => "Hello EVERYONE!")
end
end
******************
hello.html.erb
<h1>Demo#hello</h1>
<p>Hello World!</p>
<%= 1 + 1 %> <------ works
<% target = "world" %>
</br>
<%= "Hello #{target}" %> <----- works
</br>
<% #zarray.each do |n| %> <---- line 10. Rails claims that #zarray is
not defined
<%= n %></br>
<% end %>
ActionView::Template::Error (undefined method `each' for nil:NilClass):
I copied and ran your code and it worked fine. I guess it could be down to the fact that controllers should as a rails convention be pluralized, and your controller is called DemoController and perhaps you've called demoS#action somewhere? So, generate a new controller from your terminal called:
DemosController
with the generator:
rails g controller Demos
And copy paste everything from the old controller to the new controller.
And in your routes.rb you need to first make sure you have the correct resources :demos (the name of your model) which will give you the standard RESTful resources (index, new, create, etc), but as your 'hello' method is not a part of the RESTful api, you need to create a custom route for that:
get 'hello' => 'demos#hello', :as => :hello
get = HTTP method
'hello' = The URL you want to hello.html.erb to be reachable on: localhost:3000/hello
'demos#hello' = demos is the DemosController and #hello is the action in the controller.
':as => :hello' (_path)is the named helper you can call in a link_to on any page for instance: link_to hello_path.
I am new to Ruby and Rails. I tested using a plain STRING instance variable, and THAT got passed from my controller to my template, so the issue was the array definition. Apparently the older form of array definition that was in the tutorial that I was using no longer works in the version of rails and ruby that I am using.
I am using Ruby on Rails 5.0.1 with Ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32] on Windows (rails/ruby compatibility is kosher).
#zarray = [1,2,3,4,5] <-- the array is not defined when passed to template
#zarray = Array.new << 1 << 2 << 3 << 4 << 5 <-- this works
It is a bit distressing that Ruby does not even BOTHER to complain about the format of the array definition. It just DOES NOTHING (i.e., refuses to initialize the array).
In the template:
<% #zarray.each do |n| %>
<%= n %></br>
<% end %>
I should add that #zarray = {1,2,3,4,5] works if you use it after #zarray = Array.new
In other words, at some point in the evolution of Ruby, EXPLICITLY classing arrays was introduced? It is not always clear in the documentation. The earlier tutorial I was using does NOT explicitly class the array.
The problem seems to be in the current RAILS version (5.0.1) that I am running. I has done SOMETHING to destroy the ability of Ruby to create an array using array literal syntax. When I run array definitions with literal syntax in IRB, I have no problem creating them. So Ruby is fine. It is a serious BUG in the 5.0.1 version of rails. So I think I should report it.
Welcome to Git (version 1.8.1.2-preview20130201)
$ irb
irb(main):002:0> service_mileage = [5000,15000,30000,60000,100000]
=> [5000, 15000, 30000, 60000, 100000]
irb(main):003:0> service_mileage[0]
=> 5000
irb(main):004:0> service_mileage[2]
=> 30000
irb(main):005:0>

link_to does not work in production (Heroku)

I don't have any problems using link_to locally however, as soon as I deploy to Heroku I get the following error:
users#show (ArgumentError) "arguments passed to url_for can't be handled. Please require routes or provide your own implementation"
app/views/users/show.html.erb:176:in `_app_views_users_show_html_erb__222687663100622833_69928454693640'
I am using ruby '2.2.0' and rails '4.2.0'
Any ideas on how to further debug this or replicate it locally?
Update 1. Here's the actual view code which displays pagination links. The resulting route should be /users/1?page=1 etc.
<div class="row text-center">
<%= will_paginate collection, renderer: BootstrapPagination::Rails %>
</div>
The issue was with url_helpers included in one of my models - everything worked after I removed the following include.
include Rails.application.routes.url_helpers
Using the correct url_for method in a Rails engine spec
I had the same issue with ActiveAdmin in production environment. In my case the issue was with ActionView::Helpers::FormTagHelper included at root level in one of my helpers.
I solved it moving the include statement inside a class defined in the same file.

ApplicationHelper not loaded in Rails 4 engine

Long time reader of SO here. I'm working on a Rails Engine. The big picture problem is that I get a NoMethodError on a helper method living in my Engine's ApplicationHelper. This is for work so I'm going to call the engine Blorge.
I have my helper method that is causing issues anywhere it is called. The Helper method is returning a NoMethodError. I thought maybe I needed to manually add helper Blorge::ApplicationHelper to Blorge::ApplicationController but the issue is still happening.
Am I missing something fundamental about Engines here?
Here is some actual code to give you a better idea of what I'm looking at.
index_header partial
app/views/blorge/shared/_index_header.html.erb
# require_locals is the helper method in question here
<% require_locals ['title'], local_assigns %>
<% title = title.pluralize %>
<section class="main_content-header">
<div class="main_content-header-wrapper">
<%= content_tag :h1, title %>
<div class="main_content-header-save">
<%= link_to "New #{title.singularize}", #new_path, class: "add-button" %>
</div>
</div>
</section>
Pages#home view
app/views/blorge/pages/home.html.erb
<%= render 'blorge/shared/index_header', title: "Welcome, #{current_user.full_name}" %>
...
Engine Application Helper
app/helpers/blorge/application_helper.rb
module Blorge
module ApplicationHelper
def require_locals(local_array, local_assigns)
local_array.each do |loc|
raise "#{loc} is a required local, please define it when you render this partial" unless local_assigns[loc.to_sym].present?
end
end
end
end
Engine Pages Controller
app/controller/blorge/pages_controller.rb
module Blorge
class PagesController < ApplicationController
def home
end
end
end
Engine Application Controller
app/controllers/blorge/application_controller.rb
class Blorge::ApplicationController < ActionController::Base
helper Blorge::ApplicationHelper
...
end
If I restart the server and reload the page, it will usually work just fine, and once it works, the issue doesn't come back for a couple days. After reading Helpers in Rails engine and Rails Engines: Helpers only are reloaded when restarting the server it sounds like I need to include the helper in my application controller with the to_prepare method in my engine.rb file. I am going to try this next but I most want to know if I'm missing something very basic here, If i do just have to add it to engine.rb, can someone explain why?
This might have been too much information, but I'd rather give more than not enough. Thanks in advance.
Edit
the fix seems to have been adding the helpers to application controller within engine.rb. I suspected this would be the fix, but I still have no clue why this is. Does anyone know why I should have to do this?
The Solution
config.to_prepare do
ApplicationController.helper(MyEngineHelper)
end

Template path in Rails 3

Let's say, I connected the route / to WelcomeController's index action.
Inside of the index.html.erb-Template I want to display the path of the template from Rails.root upwards, ie.
<h1> We are rendering: <%= how_do_i_do_this? %></h1>
to render to
<h1> We are rendering: app/views/presentation/index.html.erb</h1>
In Rails 2 I could access template.path, but this doesn't work anymore
Any ideas?
Because of how template rendering works in Rails, you will now be able to use __FILE__ for this instead. This works for me:
<%= __FILE__.gsub(Rails.root.to_s, "") %>
There may be a better way to do this however, but I couldn't find it when I went looking.
Ryan's answer works. If you also want to put your method in a helper, use Kernel#caller. Here is a method I'm using to do something similar:
def has_page_comment? code = nil
if code.nil?
# grab caller file, sanitize
code = caller.first.split(':').first.gsub(Rails.root.to_s,'').gsub('.html.erb','')
end
...
end

Resources