Get current controller and action name in Ramaze - ruby

Is there a way to get the currently executing controller and action name in Ramaze?
require 'ramaze'
class FooController < Ramaze::Controller
def bar
"#{controller}.#{action}" #how to get this to work?
end
end
PS: I know self.class.name would give you the class name/controller name but was wondering if this captured somewhere else in the Ramaze API. Also __method__ should give the action name but I don't want to create variables when I pass this info to templates.

You can get them with :
controller = action.node
method = action.method
See https://github.com/Ramaze/ramaze/wiki/Knowing-which-controller-or-method-triggered-view-layout-rendering

Related

How to create and call parameterised page-object classes

I am using page-factory visit, on methods to call page-object classes from spec file in ruby. I would like know how to parameterise page-object classes, passing parameters from spec file using page factory methods.
I want to log all steps information in page-object class. To do this, I created a log in spec file using the logger gem. I need to pass the log object as input parameter to page classes to capture data. Here is the code I am using to do this.
spec file that calling page class:
require './lib/pages/Test_page'
file="logs/uniusecase_#{#ncs_server['build_no']}_#{#ncs_server['test_type']}_#{time}.log"
$log=Logger.new(file)
describe 'testcase-1',:sanity do
visit Testpage, using_params: {logger: $log} do |page|
end
end
page-object class:
class Testpage
include PageObject
log = "<%=params[:logger]%>"
def goto
log ("test msg-1")
end
def testmethod()
log("test msg -2")
end
end
I am getting "NameError: undefined local variable or method `log' error message while execution. Could somebody help me in doing this?
The :using_params are stored in the class' #merged_params variable. You can get this variable by doing:
self.class.instance_variable_get(:#merged_params)
So your method would look something like:
def goto
logger = self.class.instance_variable_get(:#merged_params)[:logger]
logger("test msg-1")
end
However, if you are defining the logger in a global variable, it will already be available to the page object class (ie you do not need to pass it along). In other words, you could simply do:
def goto
$log ("test msg-1")
end

Ruby on Rails: Getting a route with Devise

TL;DR How can I achieve this to always return routes with Devise User model ID in custom controllers (i.e. redirecting to localhost:3000/profiles/504026426) with Mongoid?
I have a project that has a social profile controller that returns of a user id with Devise but it will always complain that Mongoid needs a valid ID number in order to work with this route: localhost:3000/profiles/.
# Let's say I want to return a route with id (Devise) without having
# Rails to complain that Mongoid needs to a id of some number.
# So, I have controller containing profiles in the files.
# It goes like..
class ProfilesController < ApplicationController
before_filter :authenticate_user!
# GET /profile/
def index
#user = User.find(params[:id])
end
# .. Snipped for brevity.
end
Is this the right way to do it?
Firstly, the 'params[:id]' you're trying to find the user by won't work in the index view, because you're not passing in any parameter via the url ('profiles/:id' or: localhost:3000/profiles/504026426). If you want to store a user to be available in the index view, use sessions and the current user helper method. See here.
If you want your GET method to work with the 'params[:id]' it would look like:
get 'profile/:id' => 'profiles#show'
make sure it matches a show function in your controller
def show
# this would work with: localhost:3000/profiles/504026426
#user = User.find(params[:id])
end

ruby, no method error

I am receiving the following error when running my below ruby script:
s3parse.rb:12:in `block in <class:AccountLog>': undefined method `extract_account_id' for AccountLog:Class (NoMethodError)
I dont think it should be a class method, is there a reason its not taking my method into account?
class AccountLog
attr_accessor :bytes, :account_id, :date
def extract_account_id(line)
line.match(%r{accounts/(\d+)}).captures.join.to_i
end
s3log = File.open('vidcoder.txt').each do |line|
account_log = AccountLog.new
account_log.date = line.match(%r{\[[^:]*}).to_s.delete"[" #need to finish this regex to make it work
account_log.account_id = extract_account_id(line)
account_log.bytes = line.match(%r{^.*\s+HTTP.*\s+-\s+(\d+)\s+}).captures.join.to_i
puts "\n"
puts "The api request on #{account_log.date} was fromm account number #{account_log.account_id} and the bytes were #{account_log.bytes}"
end
end
def extract_account_id will define an instance method.
In the way you call it, you need a class method instead.
Define it like this:
def self.extract_account_id(line)
or, as you already have an AccountLog instance, use it to call extract_account_id:
account_log.account_id = account_log.extract_account_id(line)
Please note that with second way you do not need to alter method definition, just call extract_account_id via account_log instance.
And i guess you would want to put s3log = File... outside class definition.
Or use a constant instead: S3log = ...
Then you'll can access it as AccountLog::S3log
Is there any reason you don't think it should be a class method? You are using it in the context of a class method and that's why it it's saying no such method for class AccountLog.
If you name your method as self.extract_account_id(line) I'm sure it will work.
From what you are trying to do I think this is what you are looking for?
class AccountLog
attr_accessor :bytes, :account_id, :date
def self.extract_account_id(line)
line.match(%r{accounts/(\d+)}).captures.join.to_i
end
end
s3log = File.open('vidcoder.txt').each do |line|
account_log = AccountLog.new
account_log.date = line.match(%r{\[[^:]*}).to_s.delete"[" #need to finish this regex to make it work
account_log.account_id = extract_account_id(line)
account_log.bytes = line.match(%r{^.*\s+HTTP.*\s+-\s+(\d+)\s+}).captures.join.to_i
puts "\n"
puts "The api request on #{account_log.date} was fromm account number #{account_log.account_id} and the bytes were #{account_log.bytes}"
end
While you could take the class method approach, there seems to be a little more going on.
You should put the extraction logic in a method in itself rather than let it hangout in your class. Then outside of the class, have an instance of AccountLog where you can call on the methods for log and account id extraction. At that point you can do something with those values.
Class method or not is a detail we can explore after the class is a bit more clean I think.

How to call a page-object from a class.rb at Support folder

I am using the page-object gem. Suppose i have a page-object on features/bussines/pages/booking_page.rb for a page like:
class Booking
include PageObject
span(:txtFirstName, :id => 'details_first_name')
end
...and i use a "tools" class located at features/support/tools.rb with something like:
class MyTools
def call_to_page_object
on Booking do |page|
puts page.txtFirstName
end
end
end
...but this approach fails because calling to the object from the class is not allowed:
undefined method `on' for #<Booking:0x108f5b0c8> (NoMethodError)
Pretty sure i'm missing some concept on the way to use the page-object from a class but don't realize whats the problem. Can you please give me an idea about what could be wrong here, please?
Thank you very much!
============================
Justin found the reason why the call to the class crash. The final class code results:
class MyTools
#Include this module so that the class has the 'on' method
include PageObject::PageFactory
def initialize(browser)
#Assign a browser object to #browser, which the 'on' method assumes to exist
#browser = browser
end
def getCurrentRewards
on Booking do |page|
rewards_text = page.rewards_amount
rewards_amount = rewards_text.match(/(\d+.*\d*)/)[1].to_f
puts "The current rewards amount are: #{rewards_amount}."
return rewards_amount
end
end
end
And the call to the function:
user_rewards = UserData.new(#browser).getCurrentRewards
Why it did not work me? Two main reasons:
I didn't pass the browser object to the class <== REQUIRED
I didn't include the PageObject::PageFactory in the class <== REQUIRED for the "on" method.
Thanks all!
To use the on (or on_page) method requires two things:
The method to be available, which is done by including the PageObject::PageFactory module.
Having a #browser variable (within the scope of the class) that is the browser.
So you could make your MyTools class work by doing:
class MyTools
#Include this module so that the class has the 'on' method
include PageObject::PageFactory
def initialize(browser)
#Assign a browser object to #browser, which the 'on' method assumes to exist
#browser = browser
end
def call_to_page_object
on Booking do |page|
puts page.txtFirstName
end
end
end
You would then be calling your MyTools class like:
#Assuming your Cucumber steps have the the browser stored in #browser:
MyTools.new(#browser).call_to_page_object
What are you trying to do?
Did you read Cucumber & Cheese book?
Pages should be in the features/support/pages folder. You can put other files that pages need there too.
If you want to use on method in a class, you have to add this to the class:
include PageObject
The code from MyTools class looks to me like it should be in Cucumber step file, not in a class.
Your class should use the extend keyword to access special class methods like span:
class Booking
extend PageObject
span(:txtFirstName, :id => 'details_first_name')
end
I hope this works.

Delegating to another action in Ramaze

I'd like to delegate to the Show action from the Index action if an id was passed. I can't seem to get it to work, what am I doing wrong here?
require 'ramaze'
require 'slim'
class UsersController < Ramaze::Controller
engine :slim
def index(id=nil)
if id
render_full "/users/show/#{id}" #id was passed, "show" the item
end
#alright just render the "index.slim" here...
end
def show(id)
u=User[id] #ORM stuff...
end
end
Ramaze.start
You have to call return render_full(...) opposed to just render_full(), without this the code below it will be executed regardless of whether or not an ID was specified.
You can call return show(id) instead of render_full "/users/show/#{id}"

Resources