Here is a strange issue.
In my application helper, there is a method named test, and an other method named article_url. I have the article resource, and generate its url_helpers. In the test method, i call article_url, but it access the url_helper method instead of the method i defined in helper.
My project runs well in Rails 3.0, but when i upgrade to 3.2, it raise the issue. And under 3.2, development mode runs well but production raise issue.
Please forgive my poor english :-)
Sorry, code like this:
# application_helper.rb
module ApplicationHelper
...
def article_url(article, html_suffix = true)
if article.redirect_to.present?
article.redirect_to
else
url = "#{Settings.host}/articles/#{article.created_at.strftime("%Y-%m-%d")}/#{article.id}"
url += ".html" if html_suffix
url
end
end
...
def render_article_list(article)
link_to(xxx, article_url(article), {:target => "_blank"})
end
end
Rename your helper method. If you have a helper named article_url and a resource named article then article_url will be ambiguous between the routes and the helper. If you don't think this is the issue, post some code to help us narrow down the problem.
Related
I'm using the rails-footnotes gem in my Rails 3.2 applications, but I can't seem to get the footnotes to register the existence of any partials: it always shows a zero partial count.
To be able to know how many and what partials are being displayed on a view easily like this is, I think, immensely useful, so I would really like to get this working (the rest works great), but I'm not sure what the problem is and am hoping someone else has had the same problem and was able to resolve it. Is there a setting I've potentially missed?
I don't think it's relevant, but I'm using OSX 10.6.8 and had some issues getting the gem to work with Sublime Text 2 properly, but they did get resolved (details in this StackOverflow answer).
Update:
It seems that the issue only exists for haml templates, as I am getting expected output for erb templates. It would seem that only erb templates are counted/recognized...?
Update 2:
#DonHopkins' answer below got all my Haml templates to register with Rails Footnotes. I put it in my config file as follows:
config/initializers/rails_footnotes.rb
if defined?(Footnotes) && Rails.env.development?
Footnotes.run! # first of all
Footnotes::Notes::LogNote::LoggingExtensions.module_eval do
def add(*args, &block)
super
logged_message = args[2] + "\n"
Footnotes::Notes::LogNote.log(logged_message)
logged_message
end
end
# ... other init code
Footnotes::Filter.prefix = 'subl://open?url=file://%s&line=%d&column=%d'
end
I had a similar problem, although I am using erb templates, not haml. I fixed it with a monkey patch to rails-footnotes.
Looking at the rails-footnotes code (version 3.7.9), it looked to me like the problem is in this method:
module Footnotes
module Notes
class LogNote < AbstractNote
...
module LoggingExtensions
def add(*args, &block)
logged_message = super
Footnotes::Notes::LogNote.log(logged_message)
logged_message
end
end
...
end
end
end
The add method is assuming that super returns the message that is being logged, but in my testing super was returning a boolean value. To solve the problem, I created a file called footnotes_patch.rb with the following:
Footnotes::Notes::LogNote::LoggingExtensions.module_eval do
def add(*args, &block)
super
logged_message = args[2] + "\n"
Footnotes::Notes::LogNote.log(logged_message)
logged_message
end
end
If you want to try the solution, put that file in config/initializers, then restart your application.
I know that this not an "acceptable" practice but as a background process I am caching a rendered Rails partial into the database for faster output via JSONP. I have found many resources on the topic and successfully output a Rails 2.3.x partial within a ActiveRecord model, BUT if I use dynamic URLs within a partial Rails blows up.
I get a successful output (minus the dynamic URLs) with this...
def self.compile_html
viewer = Class.new(ApplicationController)
path = ActionController::Base.view_paths rescue ActionController::Base.view_root
Question.all.each do |q|
q.html = ActionView::Base.new(path, {}, viewer).render(:partial => "questions/cached_output", :locals => { :question => q })
sleep 1 # hold for complete output and debugging only
q.save( false ) # bypass validations
end
return "Caching complete"
end
I have tried including ActionController::UrlWriter Modules and ActionView::Helpers::UrlHelper with no luck. I cannot seems to find the instantiation/inclusion order to allow the partial to access ActionController::Base.new.url_for() to write the dynamic routes to the partial.
I did attempt a similar process as RoR: undefined method `url_for' for nil:NilClass without luck
I know that render_anywhere is a solution for Rails 3.x apps, but I am working in Rails 2.3.11
Thoughts?
I have an old app that I had to do something similar (but made use of polymorphic_path and polymorphic_url) in a model.
The following includes gave me access to url_for and polymorphic_path etc.
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TagHelper
include ActionController::PolymorphicRoutes
include ActionController::UrlWriter
I have a ruby gem, poirot, which enables the use of mustache templates in Rails. The template handler I have was extending from ActionView::Template::Handler, however this appears to be deprecated in Rails 3.1.
I have re-factored the handler to comply with the deprecation warnings. In doing this I am now unable to pass locals, or the view context, to the template. I can't seem to find out how to get this working with Rails 3.1.
module Poirot
class Handler
attr_reader :template
def initialize(template)
#template = template
end
def self.call(template, *args)
self.new(template).call
end
def call
view_path = "#{template.virtual_path}_view"
abs_view_path = Rails.root.join('app/views', view_path)
view_class = begin
view_path.classify.constantize
rescue NameError => e
Poirot::View
end
"#{view_class}.new(self, '#{template.source.gsub(/'/, "\\\\'")}').render.html_safe"
end
end
end
In my code above for the handler I get passed the template, which is an instance of ActionView::Template. But I'm not sure how to get the view context, which should include the locals etc
Can someone point me in the right direction?
Okay I have a solution, I'm not sure it is the best, it feels a little hacky to me!
In my view class I have managed to get access to the locals by doing the following:
locals = view_context.send(:view_renderer).send(:_partial_renderer).instance_variable_get("#locals") || {}
This feels a little messy as both view_renderer and _partial_renderer are private, and there is no proper accessor to the locals ivar.
I'm still hoping there is a better way to do this!
I spent about 4 hours investigating source code to find a solution, and now it's seems very simple:
just add "local_assigns" where you are want to eval it and use.
For example:
"#{view_class}.new(self, '#{template.source.gsub(/'/, "\\\\'")}', local_assigns).render.html_safe"
this string will be evaluted inside the module context - ActionView::CompiledTemplates and local_assigns will be accessible there.
I'm trying to write spec for inherited_resources controller. I decided to mock all integration with the database using rspec's mock_model. Unfortunately I can't write spec for create and update action because I'm getting the following error: https://gist.github.com/936947
Can someone help me with this issue?
I was having the same issue using flexmock.
the cause is that it does not use the update_attributes method to make the routing decision. It checks the resource.errors to see whether it is empty.
So to get it to respond properly, we will need to mock out the errors method as well.
Here is the pertinent code #line 248 in lib/inherited_resources/base_helpers.rb
def respond_with_dual_blocks(object, options, &block) #:nodoc:
args = (with_chain(object) << options)
case block.try(:arity)
when 2
respond_with(*args) do |responder|
blank_slate = InheritedResources::BlankSlate.new
if object.errors.empty?
block.call(responder, blank_slate)
else
block.call(blank_slate, responder)
end
end
when 1
respond_with(*args, &block)
else
options[:location] = block.call if block
respond_with(*args)
end
end
The failure messages are about the inability to access named routes from inside the controller, so I'm not sure that this has anything to do with mock_model. Have you tried the same examples using real models?
SOLVED. See note 2 and 3.
I guess I just don't understand classes in rails 3 + ruby 1.9.2...
We're using actionmailer in conjunction with delayedjob. It all works fine EXCEPT I'm just trying to pretty-up some phone numbers and I'm trying to put a simple method pretty_phone (to format a phone number) SOMEWHERE that doesn't throw the error:
Class#sample_email failed with NoMethodError: undefined method `pretty_phone'
I've tried it in model_helper.rb, application_helper.rb, and in the class for what I guess is the model for our email foo_mailer.rb (FooMailer < ActionMailer::Base)
Our project setup is this:
app
controllers
widgets_controller.rb
helpers
application_helper.rb
widgets_helper.rb
mailer
foo_mailer.rb ***
models
widget.rb
views
widget
(usual edit,show, etc views)
foo_mailer
sample_email.html.haml ***
This is the simple method I'm trying to add:
# num is a string, always in format 12223334444 we want (222)333-4444
def pretty_phone(num)
return "(" + num[1,3] + ")" + num[4,3] + "-" + num[7,4]
end
foo_mailer.rb is very simple:
class FooMailer < ActionMailer::Base
helper :application **** THIS ALMOST MAKES IT WORK SEE NOTE 2
include ApplicationHelper **** AND THIS ALSO IS REQUIRED NOTE 3
default :from => "Support <support#mydomain.com>"
def sample_email(thewidget)
#widget = thewidget
send_to = #widget.contact_email
if !send_to.blank?
mail :to => send_to,
:subject => "alert regarding #{pretty_phone(#widget.userphone)}"
end
end
end
and down in our view for the email we also use #{pretty_phone(#widget.userphone)}
I'd really like to understand why I can't put that helper in application_helper or even foo_mailer.rb and have it work -- and where it SHOULD go?
(Currently I have the helper in application_help.rb and ALL of our widget erb views can use it fine... it's just the email view and/or the class file foo_mailer.rb that throw the error.)
NOTE2
by adding helper :application at the top of foo_mailer.rb NOW the pretty_phone() helper method in application_help.rb works in the foo_mailer VIEWs but NOT in the foo_mailer.rb itself. So for example where I want to to pretty_phone() in the subject line of the email it will not work. But in the actual emails (the views) it does work.
That just seems bizarre to me - any suggestions?
NOTE 3
Adding the 'include' AND the 'helper' is what was needed.
Where do I put helper methods for ActionMailer views?
i think this is exactly what you need.
the answer is posted as part of the question. thanks to all those whose comments led to finally figuring it out. I'm trying to "mark" this question as answered so people won't feel like they need to supply another answer, but somebody deleted my earlier answer. so I'm adding this back in again so in a day or two the system will let me flag this quesiton as answered.