Working with distance_of_time_in_words in Rails 3 - time

I am trying to make use of Rail's distance_of_time_in_words helper but I'm getting an Undefined Method Error for some reason. Here's my code:
def confirm_has_quota
last_upload = current_user.photos.last.created_at
remaining_time = distance_of_time_in_words(1.day.ago, last_upload)
if last_upload < 1.day.ago
return true
else
flash[:error] = "You are allowed 1 upload per day. Please try again in" + remaining_time + "."
redirect_to(:back)
end
end
Which gives me "undefined method `distance_of_time_in_words'". Anyone see what I'm doing wrong here? Thanks.

The distance_of_time_in_words method is an ActionView Helper, thus needs to be called from the View (not the controller).
http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html

Or you can access the same through the view_context which is available inside the controllers.
view_context.distance_of_time_in_words

Related

Ruby unknown + on trying to join 2 strings

So, I'm learning Ruby and immediately, have stumbled upon something rater peculiar when trying to concatenate 2 strings to one. Here's the code, with irrevelant parts stripped, lets just say Sinatra runs it:
class CMS
# Set the site path root.
#sitePath = "./site"
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
And on loading the page, I am greeted with
NoMethodError at /
undefined method `+' for nil:NilClass
on the renderCache = File.readlines(#sitePath + "index.liquid") line. Why is it refusing to concatenate the strings?
You can't set instance variables at the class level. You need to set them in an instance method.
Look's like you're using sinatra so you can do this:
See here for how to make a "before filter" like one does in Rails apps. This solution is for the modular style of Sinatra app.
To show an example:
class CMS < Sinatra::Base
before do
#sitePath = "./site"
end
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
CMS.run!
You could also keep your existing code if you use a constant instead of an instance variable:
class CMS
# Set the site path root.
SitePath = "./site"
get '/' do
renderCache = File.readlines(CMS::SitePath + "index.liquid")
end
end
To explain how I read your error and looked for the error:
undefined method '+' for nil:NilClass means you're calling + on something which is nil. Referencing the code shows that the nil variable is #sitePath. Undefined instance variables will evaluate to nil. This is different than standard variables, which will raise an undefined variable error.

Getting undefined method `when_visible' for #<Array:0x3db6090> (NoMethodError) in PageObject

I’m getting Getting undefined method `when_visible' for # (NoMethodError) when I used built –in method from PageObject Ruby gem. Here is my code:
class HomePage
include PageObject
links(:search_types, :css => ".search-type")
def select_search_type
search_types_elements.when_visible(timeout=10)
search_types_elements.find { |type| if type.text=='Resort'; type.click; break end }
end
end
Could someone please help? Thanks a lot!
Updated to reflect discussion.
page-object gem handles the plural of its basic accessors. Page-object ultimately generates
search_types_elements = #browser.find_elements(:css, ".search-type")
so you will need to follow it with something like (Updated)
search_types_elements.find { |type|
type.when_visible(timeout=10)
if type.text=='Resort'; type.click; break end
}
You should add something to the page class constructor to wait for the page to completely load. Unfortunately, there isn't a simple way to do this. Much depends on the page specifics. I usually start by waiting for the jquery queue to have zero length. Something like this:
WebDriverWait(self.selenium, 10).until(lambda s: s.execute_script("return jQuery.active == 0"))

I have a Ruby undefined local variable or method error

When I try to run this code:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new(chicago, tokyo)
I get an error that tells me that one of my parameters is undefined local variable. I was just trying to create an instance using Message, and was curious as to why this was not working. I thought this would work as I am calling the class.
Problem
With your current code, you get this error:
undefined local variable or method `chicago' for main:Object (NameError)
because the way you instantiated the Message class:
my_message = Message.new(chicago, tokyo)
chicago and tokyo are interpreted as variable or method that you did not actually define or declare, that's why you got that error.
Solution
I think, you just wanted to pass two string objects (putting chicago and tokyo in the quotes) as the arguments of Message.new call like this:
my_message = Message.new('chicago', 'tokyo')
This will solve your problem.
Hope this makes it clear why you are getting the error and how to solve the problem.
The 'undefined local variable' error is showing up because there's no value associated with chicago or tokyo. If you want to just pass them as strings, wrap them in quotation marks instead, like this:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new("chicago", "tokyo")

Rails 3.1 and static pages

I'm just in the middle of upgrading a large application from Rails 3 to Rails 3.1 and struck a problem with my implementation of the pages controller:
when templates doesnt exist
should render the 404 page (FAILED - 1)
Failures:
1) PagesController automatic paths when templates doesnt exist should render the 404 page
Failure/Error: get 'base_page_processor', :base_page => 'something_that_doesnt_exist'
NoMethodError:
undefined method `map' for "pages":String
# ./app/controllers/pages_controller.rb:5:in `base_page_processor'
# ./spec/controllers/pages_controller_spec.rb:37:in `block (3 levels) in <top (required)>'
Finished in 0.10557 seconds
4 examples, 1 failure
Failed examples:
rspec ./spec/controllers/pages_controller_spec.rb:36 # PagesController automatic paths when templates doesnt exist should render the 404 page
This did work in Rails 3.0. Something must of changed with the template_exists method. Here is the controller:
class PagesController < ApplicationController
def base_page_processor
view_prefix = "pages"
if params[:base_page].present? && template_exists?(params[:base_page], view_prefix)
render "#{view_prefix}/#{params[:base_page]}"
else
#TODO : Notify missing url via email error or error notification service
render '/public/404.html', :status => 404
end
end
end
Solution code:
class PagesController < ApplicationController
def base_page_processor
view_prefix = ["pages"]
if params[:base_page].present? && template_exists?(params[:base_page], view_prefix)
render "#{view_prefix[0]}/#{params[:base_page]}"
else
#TODO : Notify missing url via email error or error notification service
render '/errors/404.html', :status => 404
end
end
end
I also noticed that it wasn't rendering the error views (ie: /public/404.html) so I created a directory app/views/errors and put all the error static pages in there and just render them now. It works.
Thanks Andrew.
The template_exists method parameters indicate that the second parameter, prefix, should be an array. Normally Rails methods accept both by converting something to an array if not, so this is slightly unusual.
exists?(name, prefixes = [], partial = false, keys = [])
This method is also aliased as template_exists?
# File actionpack/lib/action_view/lookup_context.rb, line 93
def exists?(name, prefixes = [], partial = false, keys = [])
#view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys))
end
So making view_prefix = ["pages"] should work? (and modifying the remaining string interpolation accordingly)

How does rescue_action in Rails3 work?

I would like to implement this
class SecurityTransgression < StandardError; end
def create
raise SecurityTransgression unless ...
end
class ApplicationController < ActionController::Base
def rescue_action(e)
case e
when SecurityTransgression
head :forbidden
end
end
end
from the this blogpost.
The problem is it does not work. I dont see a forbidden page but standard Rails error page "SecurityViolation in MyController#action". I digged that some rescue_action methods works only in the production mode. I tried that and it is the same. No change.
My question: is there any good documentation of the rescue_action method (and others)? Does this work under Rails 3.0? Because it seems this is some old
Take a look at rescue_from at the API documentation.
The rescue_action method is normally called internally with the #_env hash being passed as a parameter. The method is expecting the Exception instance to exist within the "action_dispatch.rescue.exception" key.
If you must use the rescue_action method directly, you can do the following:-
#_env[ "action_dispatch.rescue.exception" ] = exception
rescue_action( #_env )
or even more simple:-
rescue_action( { "action_dispatch.rescue.exception" => exception } )

Resources