How to call a helper method in view - ruby-on-rails

I have this code in my helper:
def app_state(app)
state = app.operator_apps.map(&:is_production)
if state.include?(true) and state.include?(false)
"Sandbox/Production"
elsif state.include?(true)
"Production"
else
"Sandbox"
end
end
and in my view I have done this:
<%= app.app_state %>
I get the following error:
ActionView::Template::Error (undefined method `app_state' for #):
Please help me out in solving this.

The error you are getting will persist unless an app_state method is defined somewhere within app's model.
Try calling the helper method like so:
<%= app_state(app) %>
Now the app object is being passed in as the argument of the app_state method, instead of the method being called on the object itself.
Hope that helps!

Related

Rails use request.url in mailer

In a view this code works fine:
<% if request.url.include?('ndeavor2s.com') %>
<p>Staging</p>
<% end %>
But, in mailers/comment_mailer.rb this code doesn't:
if request.url.include?('ndeavor2s.com')
fromurl = "#mail.ndeavor2s.com"
end
I get:
undefined local variable or method `request'
request is an action controller thing, not available in action mailer directly. If you need, just pass the request object into the mailer object when you instantiate it.

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

Undefined AWS::S3 when define a method in helper

I am following this tutorial http://net.tutsplus.com/tutorials/create-a-simple-music-streaming-app-with-ruby-on-rails/, but use the aws_sdk instead of aws_s3. I see basically they do the same thing. In the download part, I put the the download function into the model and it did show correctly the url to download, but from there I don't know how to trigger download so I moved the function to the helper and invoke it straight from view. From there rails keep complaining about undefined method `model_name' for URI::HTTPS:Class
This is the download method
def download song_key
bucket = AWS::S3.new.buckets['mybucket'] # error from this line because undefined AWS::S3
song = bucket.objects[song_key]
song.url_for(:read, expires: 10*60)
end
This is the views
<% #songs.each do |song| %>
<%= link_to "download", download(song.key) %>
<% end %>
Any idea how to fix it ? Thanks
You're reading the stack trace slighty wrong - it's not your helper method raising the exception, but something inside link_to.
The url_for method is returning a URI::HTTPS instance. When the second argument to link_to is something other than a string, it assumes that it's an activemodel class and tries to find the appropriate route from that. For example if you do
link_to 'Show', person
and person is an instance of Person, link_to will end up generating the url from person_path(person).
URIs aren't active model, so this process of finding the appropriate route fails. All you need to do is turn the URI into a string, for example
def download_url song_key
bucket = AWS::S3.new.buckets['mybucket'] # error from this line because undefined AWS::S3
song = bucket.objects[song_key]
song.url_for(:read, expires: 10*60).to_s
end
Apparently the equivalent method in aws_s3 returning strings rather than URI objects which is qhy the tutorial you are following doesn't do this.

undefined method `fragment_for' for nil:NilClass on render partial with cache

I have this piece of code in a partial on some code for rails 2.3.14:
<% cache "some_partial_#{some_id}" do %>
....
<% end %>
Works fine when rendering it in a view but I get:
undefined method `fragment_for' for nil:NilClass
when I try to do this in a model:
ActionView::Base.new("app/views").render(:partial => "home/temp"}
I can see the issue occuring in actionpack-2.3.14/lib/action_view/helpers/cache_helper.rb:35
def cache(name = {}, options = nil, &block)
#controller.fragment_for(output_buffer, name, options, &block)
end
I'm not sure what exactly it expects to find in #controller.
In short: don't render partials from models - they should contain only business-logic. Error occurs since cache invokes controller object which you don't have initialized since you are bypassing view rendering logic here.
UPDATE:
The only way i see it is to get controller instance and pass it as param. How to get controller instance inside model is up to you. I think this question could be helpful Try
ActionView::Base.new("app/views", {}, #your_controller_instance).render(:partial => "home/temp")
You may be able to add:
include ActionController::Caching
to your class.

Creating a form Ruby on Rails

I'm trying to create a form on my website but I get this error:
undefined method 'model_name' for NilClass:Class
says the error is on line #33.
On line 33 I've got <%= form_for #try do |f| -%>
A view does not exist in isolation. You need to have your controller set up all the variables that you might need in the view.
So, assuming this is an edit view, you'll need to have code in your controller's edit action, something like this:
def edit
#try = SomeModel.find params[:id]
end
This will set up the #try variable and provide it to the view.
The #try variable must be nil. How is it set? Are you certain it will always contain a valid object?
You need to link your form to a specific model. In your controller, what code is defining #try? Whatever it is seems to be failing to specify a new or current model instance.
If you are using the code in new.html.haml or new.html.erb view file
def new
#try = ModelName.new
end

Resources