Call helper method from custom view Rails - ruby-on-rails

In ApplicationHelper, I have method called finTime.
def finTime(time)
end
In delayed_job I have render_to_string function
class ExportJob < Struct.new(:time1,:time2, :survey_id)
def perform
ac = ActionController::Base.new()
html = ac.render_to_string(:template => "pages/exportPdf.html.erb",:layout => "layouts/exportPdf",:formats => :html
end
end
In exportPdf.html.erb I call the function finTime
<%= finTime(f.created_at) %>
I got the error: "ActionView::Template:Error: undefined method 'finTime' for #<#Class:0x6db8eb0>: 0x8321928>"
So I want to ask how I can call finTime method from exportPdf.html.erb in this case. I tried to use include and helper but it does not work.
Thank you!

There's not a lot of information to go on here, but one possibility could be that in your definition there are no arguments - it's just finTime
but in the call you give an argument of f.created_at - maybe that's causing the error, maybe not. what is the full error?
related, the general practice for method names is snake case, so finTime should be fin_time.
edit: Without seeing more of your code it's still difficult, for example
<%= finTime(f.created_at) %>
Is that what it's in your code? finTime() is a method, so it has to be called on a model - model.finTime(time)
there's also an end parenthesis missing from this line:
html = ac.render_to_string(:template => "pages/exportPdf.html.erb",:layout => "layouts/exportPdf",:formats => :html
if both of those things are only problems in your question, and not in your code, try replacing finTime() with inspect or methods in your partial and see what happens. If there's still an error, you'll know you have to look elsewhere, and if not you'll get some information that might help you sort out the trouble. Good luck!

Related

Rails 2 Render ERb template in controller?

This code in the controller
av = ActionView::Base.new(Rails::Configuration.new.view_path)
av.extend ApplicationHelper
content = av.render(:file => "show", :locals => { :user => #user })
and the show.html.erb have the link_to helper , operation code error
undefined method `url_for' for nil:NilClass
I add av.extend ActionController::UrlWriter in the controller , still error
undefined method `default_url_options' for ActionView::Base:Class
Try:
content = render_to_string(:file => "show", :locals => { :user => #user })
Usually, in Rails, when something is very hard, it is because you are not approaching the problem from an ideal angle. I can't really answer this question directly, other than to advise not to do this. Ideally, view logic should be in the view, and not the controller. With a few rare exceptions, like using a link_to helper in a flash message (which can be easily solved), these concerns should be separated. This does not seem like one of those exceptions. Instead, I would recommend one of the following (slightly more Rails-y) techniques:
Option 1:
It looks like you are trying to render the view for the show action. This can easily be accomplished by using render :action => 'show' (docs). This will not run the code for the action, just use that view.
Option 2
In the event that option 1 is not viable in your situation, you may alternatively consider some variation of the following technique. Render the default view, as normal. Move the existing content of the view into a partial, and your new content into a partial of its own. Then in your view, simply toggle the partial to render based off of an appropriate condition - the existence of #user, for this example: render :partial => #user ? 'new_content' : 'existing_content'. Depending on your application structure, it may be that this can be further simplified by just rendering the same partial from your show view and the view for the action referenced in the question.
I think keeping the various elements of an application isolated into their intended concerns not only makes this easier to develop and maintain by following the principle of least astonishment, but also usually makes the application much easier to test, as well. Sorry for not answering your question - hope this helps, anyway.
I suppose it was called outside controller so I do it this way in Rails 3:
av = ActionView::Base.new(Rails.configuration.paths["app/views"])
av.class_eval do
include ApplicationHelper
include Rails.application.routes.url_helpers
default_url_options[:host] = 'yoursite.com'
def protect_against_forgery?
false
end
end
#result = av.render(:file => "show", :locals => { :user => #user })

Getting Formtastic in ActiveAdmin to use custom form input builder

UPDATE: So, I've found this, and apparently that's why this old way of doing things isn't working, ActiveAdmin must use Formtastic 2.x. As directed, I've now created a file in app/inputs/date_picker_input.rb that looks like this:
class DatePickerInput
include Formtastic::Inputs::Base
def to_html
puts "this is my datepickerinput"
end
end
And my controller now looks like this:
f.input :open_date, :as => :date_picker
f.input :close_date, :as => :date_picker
But now I'm running into this error:
ActionView::Template::Error (undefined method 'html_safe' for nil:NilClass):
1: render renderer_for(:edit)
Any thoughts?
I've ran into a problem with Formtastic automatically formatting dates into a format I'm not wanting (Y-m-d h:i:s Z) when I try to render :as => string so I can use a datepicker on the field. In trying to solve this, I came across this solution.
It seems to make sense and is the exact same problem I am dealing with. However, I don't seem to be able to implement the fix, and I'm wondering if it's because Formtastic is being used through ActiveAdmin. So, here's what I've tried to do:
In the controller, I've changed the method as such:
f.input :open_date, :as => :date
I also tried this, though my problem is not even being able to get to this point:
f.input :open_date, :as => :date_input
I created a file at lib/datebuilder.rb with the following code:
class DateBuilder < Formtastic::SemanticFormBuilder
def date_input(method, options)
current_value = #object.send(method)
html_options ||= {:value => current_value ? I18n.l (current_value) : #object.send("#{method}_before_type_cast")}
self.label(method, options.delete(:label), options.slice (:required)) +
self.send(:text_field, method, html_options)
end
end
I'm not sure that will even fix the format as I want, but I assume if I can just get Formtastic to use this method I can alter it as needed (currently took this from the solution mentioned in link above).
This article mentions you need to add a line to your formtastic intializer to use this custom input:
Formtastic::SemanticFormHelper.builder = Formtastic::DateBuilder
I did not have this initializer file in config/initializers so I added it (config/initializers/formtastic.rb) with the line above. The problem I am now running into is this error when trying to startup the Rails app:
../config/initializers/formtastic.rb:1:in '<top (required)>': uninitialized constant Formtastic::SemanticFormHelper (NameError)
I have also tried this syntax in that file instead:
module Formtastic
module SemanticFormHelper
self.builder = DateBuilder
end
end
which gives me this error instead: ../config/initializers/formtastic.rb:3:in '<module:SemanticFormHelper>': uninitialized constant Formtastic::SemanticFormHelper::DateBuilder (NameError)
If I'm going about this in completely the wrong way please let me know, otherwise any help on getting Formtastic to use this custom input type would be amazing!
Alright, finally figured out the right way to do this.
My controller stayed the same as seen above in the update. However, here's what I changed the DatePicker custom input file (app/inputs/date_picker_input.rb) to look like:
class DatePickerInput < Formtastic::Inputs::StringInput
def to_html
"<li class='string input required stringish' id='question_#{method.to_s}_input'>" +
"<label class=' label' for='question_#{method.to_s}'>#{method.to_s.gsub!(/_/, ' ').titleize}*</label>" +
"<input id='question_#{method.to_s}' name='question[#{method.to_s}]' type='text' value='#{object.send(method)}' class='hasDatePicker'>" +
"</li>"
end
end
Hopefully this will help someone else running into the same problem! Btw, the hard-coded "question" and "required" is because I will only use this custom input on question objects. There is likely a way to dynamically get this information, but I decided against putting more work in to figure that out (this was enough of a headache on its own!)

Correct syntax for nested sortable_element? Getting nil object

I followed Ryan Bates' rails tutorial on setting up a sortable list of objects. With some modifications, it's now working to the point where I can drag and drop a list of "belongs to" elements on a 'has many' page, and the post action is sent to my controller... Which then gives a 500 error
NoMethodError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each_with_index):
app/controllers/cuttings_controller.rb:87:in `sort'
I believe this is because while Ryan's controller knew which cutting it's dealing with, mine needs the parameters passed to it.
Here is the line on my users page (which holds 'cuttings'):
<%= sortable_element('faqs', :url => 'sort_cutting', :handle => "handle") %>
And here is the definition in the cuttings controller:
def sort
params[:cuttings].each_with_index do |id, index|
Cutting.update_all(['position=?', index+1], ['id=?', id])
end
render :nothing => true
end
Would somebody be kind enough to tell me how to tweak this so it will work properly? Which parameters should I pass? I've tried :cutting => #cutting.id, which didn't work. The post route is set up using:
match 'users/sort_cutting' => 'cuttings#sort'
... Which is a bit ugly, but the only way I could get it to work!
Thanks in advance.
I answered this by reading this post - the params didn't match 'faqs', the sortable element I was trying to deal with. Simple when you know how!

Has namedspaced routing changed in Rails 2.3?

I have an admin namespace which gives me the usual routes such as admin_projects and admin_project, however they are not behaving in the usual way. This is my first Rails 2.3 project so maybe related I can't find any info via Google however.
map.namespace(:admin) do |admin|
admin.resources :projects
end
The strange thing is for a given URL (eg. /admin/projects/1) I don't have to pass in an object to get URL's it somehow guesses them:
<%= admin_project_path %> # => /admin/projects/1
No worries, not really a problem just not noticed this before.
But if I try and pass an object as is usual:
<%= admin_project_path(#project) %> # => admin_project_url failed to generate from {:controller=>"admin/projects", :action=>"show", :id=>#<Project id: 1, name: "teamc...>
":id" seems to contain the entire object, so I try passing the id directly and it works:
<%= admin_project_path(#project.id) %> # => /admin/projects/1
This would not be so bad but when it comes to forms I usually use [:admin, #object], however:
<%= url_for [:admin, #project.id] %> # => undefined method `admin_fixnum_path'
So I can't pass in an id, as it needs an objects class to work out the correct route to use.
<%= url_for [:admin, #project] %> # => Unfortunately this yields the same error as passing a object to admin_project_path, which is what it is calling.
I can't spot any mistakes and this is pretty standard so I'm not sure what is going wrong...
Interesting. What happens when you define a to_param method on Project? For instance
class Project < ActiveRecord::Base
def to_param
self.id
end
end
This should be the default and this shouldnt be necessary. But what happens if you make it explicit? Try adding the above method then going back to your original approach of only passing around #project
I wish I could help you on this one. We have a large application with several namespaced sections. Our routes are defined in the exact method you have described and we are calling our path helper with objects. No where in the application are we accessing using the id.
Our application started on Rails 2.1 and has transitioned through 2.2 and 2.3 with no significant changes to the routing. Sorry I couldn't be more help.
Peer

How to keep track of information over several calls to render :partial

I am using attribute_fu to render a nice block of rows for a particular table.
<%= f.render_associated_form(#foo.bars, :new => 5) %>
I would like to have the bar partial have some notion of a bit of state. (Because the notion is specific to the view, I do not want to externalize this to the Bar model itself and calculate it in the controller.) For simplicity's sake, pretend it is the index of the bar in the #foo.bars list.
(I am aware that if this was the case I could use the :collection => #foo.bars to enable bar_counter... this doesn't appear to function in my tests but I have seen docs for it.)
My question -- how do I pass a variable into the partial such that I can keep and edit the state? Naively, I assumed that doing something like
<% #tmp = {:index => 1} %>
%= f.render_associated_form(#foo.bars, :new => 5, :locals => {:tmp => #tmp}) %>
#goes in the view
<%= tmp[:index] += 1 %>
would work. tmp gets passed appropriately but calling [] throws "Uh oh, you just called a method on nil". Surprisingly to me, I can do tmp.inspect, tmp.class, etc to look at the Hash, and these have the results I would expect. But tmp[:index] or tmp[:anything_I_want] cause it to blow up.
Making tmp an array had similar results.
Any ideas?
I ended up solving this in a thoroughly Rails fashion -- patching :attribute_fu to meet my needs. Hopefully I'll be able to release my patches to the community fairly soon.
The behavior you describe above seems like it must be a bug in attribute_fu, since the local isn't getting properly passed along, which it definitely should. I'd be interested to know what you did to patch it.

Resources