I have a fee column in my model and it is an integer type, so I try to create a tiny helper to add a dollar sign neatly in front. Which means, instead of writing:
span = "$#{#object.fee}"
I can write something like
span = #object.fee.dollar
So I created the tiny helper.
module ApplicationHelper
def self.dollar
"$#{self.try(:to_s)}"
end
end
I am not sure where to put it, so basically it's now showing
undefined method `dollar' for 180:Fixnum
number_to_currency()
Rails 4.2 has this ActionView::Helper
number_to_currency(1234567890.506)
Helper
If you want to implement this as a helper, this works
module ApplicationHelper
def dollar(amount)
amount = number_to_currency(amount)
end
end
Invoke
<%= dollar(your_var_here) %>
Rails spec for number_to_currency()
http://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
Note: Other versions of Rails may have this function, you'd have to check your version.
module ApplicationHelper
def dollar(amount)
"$#{amount}"
end
end
and then:
span = dollar #object.fee
I think it's because you're in a helper, so you can't refer to self.
You can do it in your Model, or in the helper do :
def print_dollar(your_value)
Or, you can also use : number_to_currency(dollar, :unit => "$"), which will render it the way you want.
Hope it help
Your helpers are included in the view context, so you need two changes:
def dollar - because it's included in the renderer, you don't need self
Call it as dollar(#object.fee) - it's not included on the object, but in your view. If you want to call it as #object.dollar, declare the method in whatever class #object is.
Additionally, the number_to_currency helper already exists and is quite robust. Perhaps you want to use that.
Related
I'm trying to implement Decorators using the learnings from "Rails 4 Patterns" Code School course, but I'm running into trouble as I need a view helper in the Decorator class.
I want my view to have:
<%= #model_decorator.previous %>
Then in the decorator:
def previous
if object.prev_item.nil?
"Previous"
else
link_to("Previous", object)
end
end
The course suggests you make a call to the decorator within your view helper in the view file itself, but that's no good if the logic could output one result with a helper and one without. (i.e. need the output to be a link or not).
I've tried using helpers.link_to but it errors out as not providing the correct information for the url_for option. I've confirmed link_to("Previous", object) works within the view itself.
For Rails 4
include ActionView::Helpers::UrlHelper
link_to("Previous", Rails.application.routes.url_helpers.send("#{object.class.name.underscore}s_path".to_sym, object))
As for me it`s better to make a decorator for it:
class LinkDecorator
include ActionView::Helpers::UrlHelper
def initialize(label, object)
#label = label
#object = object
end
def show
link_to(label, url_helpers.send("#{object.class.name.underscore}s_path".to_sym, object))
end
def index
link_to(label, url_helpers.send("#{object.class.name}s_path".to_sym))
end
...
private
attr_reader :label, :object
def url_helpers
Rails.application.routes.url_helpers
end
end
Example usage:
LinkDecorator.new(object.name, object).show
If I understand your problem correctly, you essentially want links in a plain old ruby object.
My solution would be this:
include ActionView::Helpers::UrlHelper
link_to("Previous", Rails.application.routes.url_helpers.objects_path(object))
# assuming the object is always of one class
If the object is of a different class, than it would be possible to use the .send method to send the correct message to app ie.:
include ActionView::Helpers::UrlHelper
link_to("Previous", Rails.application.routes.url_helpers.send("#{object.class}s_path".downcase.to_sym, object))
# I'd create a function out of that line to make it a bit neater
It sounds like the error thrown by url_for comes from missing the routes and there's a few ways to include those. My solution kinda avoids that problem by using Rails.application.routes.url_helpers. Hope this helps!
In my html.erb views I can normally use code like:
if current_user.role?(:label)
"do something"
end
I'm trying to do the same in a Prawn based PDF but am getting a "undefined local variable or method `current_user'" error.
I understand I need to explicitly include a helper in my PDF class, something like:
class SalesnotePdf < Prawn::Document
include CanCan::Ability
"do pdf layout here"
end
But this doesn't appear to work? Any ideas on the correct include or other approach to this?
Thanks in advance!
EDIT:
I think current_user is actually a Devise method I need to access.
Well, current_user really is a Devise method and is available in views, helpers and controllers, but not models. A better approach would be to check the user's role in a controller and then call a specific Prawn document.
Unless each user needs a significantly different report, you could pass view_context as one of your parameters.
Controller
...
format.pdf do
...
pdf = MyPdf.new #records, reportDate, view_context
...
end
Then in MyPdf you pick that up...
def initialize(records, reportDate, view)
super()
#nonPagedTransactions = transactions
#view = view
....
So now it is available to all your methods in MyPdf (as well as other view-context helpers), if you say...
#view.current_user
It seems pluralize only works within a view -- is there some way that my models can use pluralize too?
Rather than extend things, I just it like this:
ActionController::Base.helpers.pluralize(count, 'mystring')
Hope this helps someone else!
Add this to your model:
include ActionView::Helpers::TextHelper
My favorite way is to create a TextHelper in my app that provides these as class methods for use in my model:
app/helpers/text_helper.rb
module TextHelper
extend ActionView::Helpers::TextHelper
end
app/models/any_model.rb
def validate_something
...
errors.add(:base, "#{TextHelper.pluralize(count, 'things')} are missing")
end
Including ActionView::Helpers::TextHelper in your models works, but you also litter up your model with lots of helper methods that don't need to be there.
It's also not nearly as clear where the pluralize method came from in your model. This method makes it explicit - TextHelper.pluralize.
Finally, you won't have to add an include to every model that wants to pluralize something; you can just call it on TextHelper directly.
YOu can add a method like this in your model
def self.pluralize(word)
ActiveSupport::Inflector.pluralize(word)
end
and call it in this way
City.pluralize("ruby")
=> "rubies"
This worked for me in rails 5.1 (see 2nd method, first method is calling it.)
# gets a count of the users certifications, if they have any.
def certifications_count
#certifications_count = self.certifications.count
unless #certifications_count == 0
return pluralize_it(#certifications_count, "certification")
end
end
# custom helper method to pluralize.
def pluralize_it(count, string)
return ActionController::Base.helpers.pluralize(count, string)
end
I have created a helper method for generating a li content tag with a link
def method1(attribute,path,classname={},id={})
content_tag(:li, link_to(attribute, path,:class => classname),:id => id)
end
I am calling the helper method like
<%= method1("BLOGS",blogs_path,"","blog1")%>
In the above case I gave an empty string for class as there is no need for class here, but other places need that.
But if I use an empty string for class , then "blog1" becomes the class ..
How can I resolve this?
I am working on rails 2.3.11
Look into options hashes. This is used just about everywhere in Rails and is perfect for handling clunky method invocations like that.
Agree with the other answers. Your method definition should be more like
def method1(attr, path, options={})
content_tag(:li, link_to(attribute, path,:class => options[:classname]),:id => options[:id])
end
Then you can specify what you want to pass. On the downside, i seem to remember that rails sets the classname to the id if there is no classname passed in
Ive made a nice editor in jQuery and i want to add it as a form helper method.
how would i go about making a new form helper method?
ideally id like to be able to call:
f.nice_editor :field
Part of the question is: where do you put the nice_editor code? I don't think it is a good idea to directly edit class ActionView::Helpers::FormBuilder in your installation. Instead, put your code in one of the files in app/helpers. There are several ways to add extension methods to FormBuilder.
For instance, suppose you have a helper file items_helper.rb:
module ItemsHelper
# this is one way to define new instance methods
ActionView::Helpers::FormBuilder.class_eval do
def nice_editor(conf,*opts)
...
end
end
end
Also, see this good discussion, which shows how to use self.included() to extend FormBuilder.
The object yielded to form_for is an instance of ActionView::Helpers::FormBuilder. So all you have to do is to add instance methods there.
class ActionView::Helpers::FormBuilder
def custom_field(...)
...
end
end
after some research i found that this works:
class ActionView::Helpers::FormBuilder
def nice_editor(conf)
#stuff to draw the editor
end
end
"conf" would have all the symbol options passed to it from the view. it works fine with f.