undefined method for calling methode in class - ruby

i try to call my methode check_table_exists for check my table. This methode is on my module, and i dont understand why i get this error .
i know #connexion is a Mysql2::Client instance, which doesn't include the module Sgbd. but i dont see how to include my methode ?
./yamlReadFile.rb:44:in `mysql_connection': undefined method `check_table_exists' for #<Mysql2::Client:0x000000033a7750> (NoMethodError)
$LOAD_PATH << '.'
require 'yaml'
require 'rubygems'
require 'mysql2'
require 'creatDatabase'
#binding.pry
class StreamMysql
include Sgbd
def mysql_connection(conf)
#connexion = Mysql2::Client.new(:host => conf['ost'], :username => conf['user'], :password => conf['password'], :table => conf['table'], :port => conf['port'])
if #connexion
puts check_table_exists
#connexion.check_table_exists
puts "connexion etablie"
else
puts "error connexion"
end
rescue Mysql2::Error => e
puts e.errno
puts e.error
#connexion.close
end
def read_config_file
config = YAML::load_file(File.join(__dir__, 'config.yml'))
conf = config['database']
mysql_connection(conf)
end
end
my module file with the mehode check_table_exists
module Sgbd
# class ModuleCreateDatabase
def create_database
end
def check_table_exists
query=("SHOW TABLES;")
end
end

It’s unclear why would you want to include your module in the foreign class, but it’s doable:
Mysql2::Client.include Sgbd
The line above should be put e. g. before class StreamMysql declaration.

Related

Facing issues while calling method of module(having object of class , contained in another ruby file)

I am newbie in ruby and working on making performance automation framework using using 'ruby-jmeter' gem (provided by flood.io)
I have made following files structure
Where payload.rb and request.rb contains my common utility methods . Which I am calling from test.rb
(test.rb would be going to be written by QA ppl)
Performance Automation Framework Structure
request.rb (lying under 'common' folder)
require 'ruby-jmeter' #(Consider any 3rd party gem )
require 'rubygems'
module RubyJmeter
class ExtendedDSL < DSL #'ruby-jmeter' class extending
def get_common_headers()
commonHeaderHashMap = {
'tns' => 'urn:',
'Content-Type' => 'text/xml; charset=utf-8',
'Accept-Language' => 'en-US,en;q=0.5',
'Accept-Encoding' => 'gzip, deflate'
}
return commonHeaderHashMap
end
end
end
class Request
def initialize(dsl)
#dsl = dsl
end
def soap_post_web_request(name,rawBody)
endPoint = '/SoapEndPoint'
post name: name, url: endPoint , raw_body: rawBody do
tempHeaderHashMap = get_common_headers.merge( {'SOAPAction' =>
'urn:'+name} )
finalHeaderArray = []
tempHeaderHashMap.each {|key, value|
localHashMap = Hash.new
localHashMap = {:name => key, :value => value}
finalHeaderArray << localHashMap
}
header finalHeaderArray
end # End of soapCall
end #end of soap_post_web_request
# Passes method calls through to the underlying DSL (ruby-jmeter).
def method_missing method, *args, &block
#dsl.__send__ method, *args, &block
end
end
wrappingclasses_under_single_module.rb (lying under 'common' folder)
require 'rubygems'
require 'ruby-jmeter'
require 'require_all'
require_all './'
module PerformanceAutomation
def self.MyRequest
Request.new(self)
end
end
test.rb (lying under 'testflow->simpleflow' folder)
require 'ruby-jmeter' #(Consider any 3rd party gem )
require 'rubygems'
require 'require_all' #(another 3rd party gem)
require_all '../../common/'
include PerformanceAutomation
test name:'JiraAnalyticsPerformanceFlow' do
threads name: 'NoOfUsers',scheduler: false,continue_forever: false,
count: 1 do
PerformanceAutomation.MyRequest.soap_post_web_request('soapRequestmethodName',rawdata)# End of Soap request 'soapRequestmethodName'
end # End of TestPlan
view_results_tree
puts "JMX FILE IS GONNA SAVED # "+Dir.pwd+"/CreatedJMeter_DB2Navigation.jmx"
end.jmx(file: Dir.pwd+"/CreatedJMeter_DB2Navigation.jmx")
When running test.rb , I am getting following error
`<top (required)>': uninitialized constant PerformanceAutomation (NameError)
Edit (It is working fine now)
Updated common utility files by using
request.rb
module RubyJmeter
class ExtendedDSL < DSL
def get_admin_common_headers()
commonHeaderHashMap = {
'X-XSRF-TOKEN' => '${COOKIE_XSRF-TOKEN}',
'Content-Type' => 'text/xml; charset=utf-8',
'Accept-Language' => 'en-US,en;q=0.5',
'Accept-Encoding' => 'gzip, deflate'
}
return commonHeaderHashMap
end
end
end
module API
class AdminWebService
def initialize(dsl)
#dsl = dsl
end
## Admin request for 'get_space_properties'
def get_space_properties(rawBody)
endPoint = "/AdminService.asmx"
post name: "admin_GetSpaceProperties", url: endPoint ,
raw_body:rawBody do
tempHeaderHashMap = get_admin_common_headers.merge( {'SOAPAction' =>
'http://example.com/GetSpaceProperties'} )
finalHeaderArray = []
tempHeaderHashMap.each {|key, value|
localHashMap = Hash.new
localHashMap = {:name => key, :value => value}
finalHeaderArray << localHashMap
}
header finalHeaderArray
end # End get_space_properties
end
test.rb
require 'rubygems'
require 'ruby-jmeter'
require 'require_all'
require_all '../../../common/'
defaults domain: 'example.com', protocol: 'http', connect_timeout:
'2000', response_timeout: '3000'
cookies policy: 'compatibility', clear_each_iteration: true
#'cookies' is method defined under 'ruby-jmeter'
cache clear_each_iteration: true # 'cache' is method defined under
'ruby-jmeter'
# starting testPlan 'JiraAnalyticsPerformanceFlow'
test name:"testFlowName" do
adminwebservice = API::AdminWebService.new(self)
adminwebservice.get_space_properties(Payload.get_local_payload("get_space_properties.xml"))
#Payload is another common utility class for fetching payload stuff
end
puts "JMX FILE IS GONNA SAVED #
"+Dir.pwd+"/CreatedJMeter_DB2Navigation.jmx"
end.jmx(file: Dir.pwd+"/CreatedJMeter_DB2Navigation.jmx")

How to Handle ActiveRecord Migrations in a Distributed Gem?

I am trying to write an app as a gem using ActiveRecord without Rails.
My problem is how to migrate a database already deployed by a user who will not have rake, etc. I have just distributed a schema.rb file and created the db from that. But now I want to allow users to update to a new gem and migrate their db.
I've looked at ActiveRecord::Migrator, but can't figure out how to use it.
For example, how would I tell ActiveRecord::Migrator to run all migrations up from whatever is the current_migration?
Anyone have any suggestions for how to go about this or a good reference?
After going at this fresh this morning I came up with the following which is working well:
module Byr
module Db
class << self
attr_accessor :config
attr_accessor :adapter
attr_accessor :db_name
end
def self.create_sqlite(config)
require 'sqlite3'
config = config.merge('database' => File.join(Byr.db_dir, config['database']))
ActiveRecord::Base.establish_connection(config)
end
def self.create_pg(config)
require 'pg'
# Connect to the postgres db to create the db
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres',
'schema_search_path' => 'public'))
begin
result = ActiveRecord::Base.connection.create_database(config['database'])
rescue PG::Error, ActiveRecord::StatementInvalid => e
unless e.message =~ /already exists/
raise
end
end
true
end
def self.mysql_creation_options(config)
#charset = ENV['CHARSET'] || 'utf8'
#collation = ENV['COLLATION'] || 'utf8_unicode_ci'
{:charset => (config['charset'] || #charset), :collation => (config['collation'] || #collation)}
end
def self.create_mysql(config)
require 'mysql2'
error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
begin
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.establish_connection(config)
rescue error_class => sqlerr
access_denied_error = 1045
if sqlerr.errno == access_denied_error
print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
root_password = $stdin.gets.strip
grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
"TO '#{config['username']}'#'localhost' " \
"IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
ActiveRecord::Base.establish_connection(config.merge(
'database' => nil, 'username' => 'root', 'password' => root_password))
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
ActiveRecord::Base.connection.execute grant_statement
ActiveRecord::Base.establish_connection(config)
else
Byr.warn sqlerr.error
Byr.warn "Couldn't create database for #{config.inspect}, charset: #{config['charset'] || #charset}, collation: #{config['collation'] || #collation}"
Byr.warn "(if you set the charset manually, make sure you have a matching collation)" if config['charset']
end
rescue ActiveRecord::StatementInvalid => e
ActiveRecord::Base.establish_connection(config)
end
end
def self.migrate
sys_migration_dir = File.join(Byr.install_dir, "db/migrate")
ActiveRecord::Migration.verbose = true
ActiveRecord::Migrator.migrate(sys_migration_dir)
end
def self.connected?
ActiveRecord::Base.connected? and
ActiveRecord::Base.connection_config[:adapter] == adapter
end
def self.disconnect
ActiveRecord::Base.connection_pool.disconnect!
end
# Really only for testing
def self.drop_db
ActiveRecord::Base.connection.drop_database(Byr.db_config)
end
end
end
Then, to initialize the db via the migrations:
module Byr
class << self
attr_accessor :install_dir
attr_accessor :db_dir
attr_accessor :config_dir
attr_accessor :config_file
attr_accessor :config
attr_accessor :db_config
attr_accessor :adapter
attr_accessor :database
def self.create_db
case db_config['adapter']
when /postgresql/
Byr::Db.create_pg(db_config)
when /sqlite/
Byr::Db.create_sqlite(db_config)
when /mysql/
Byr::Db.create_mysql(db_config)
else
raise ByrError "Your config.yml file specifies an unknown database adapter \'#{config['adapter']}\'"
end
end
def self.connect_db(reconnect = false)
unless reconnect
return true if Byr.connected?
end
ActiveRecord::Base.establish_connection(db_config)
end
def self.migrate
Byr::Db.migrate
end
def self.init(connect = true, adapter = nil)
adapter = canonicalize_adapter(adapter) if adapter
setup_db_config
if connect
create_db and connect_db and migrate
end
end
end
Some irrelevant parts of the code are omitted, but I hope this helps
someone else.
Much of the hard stuff comes from the rake tasks in rails.

Uninitialized constant (NameError) when using FactoryGirl in module

Here's the error I'm getting when I try to run my tests with RSpec:
C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/infl
ector/methods.rb:230:in `block in constantize': uninitialized constant User (Nam
eError)
I'm trying to run FactoryGirl with RSpec but without Rails. Here are the files that take part in the testing:
user_spec.rb
require 'spec_helper'
module Bluereader
describe User do
describe 'login' do
user = FactoryGirl.build(:user)
end
describe 'logout' do
end
describe 'create_account' do
end
describe 'delete_account' do
end
end
end
spec/spec_helper
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rspec'
require 'lib/bluereader'
require 'factory_girl'
FactoryGirl.find_definitions
spec/factories.rb
require 'digest/sha1'
FactoryGirl.define do
sequence(:username) { |n| "user-#{n}" }
factory :user do
username
encrypted_password Digest::SHA1.hexdigest('password')
full_name 'John Doe'
logged_in_at Time.now
logged_out_at 0
end
end
At this point I know that the factories.rb file is being loaded (I tried with the moronic print-debugging). When I remove the user = FactoryGirl.build(:user) line from user_spec.rb I get no errors (and the normal RSpec feedback telling me there are no tests, but no errors). If you are interested, here's my model:
require 'digest/sha1'
module Bluereader
class User < ActiveRecord::Base
has_many :categories, :foreign_key => :user_id
has_many :news, :foreign_key => :user_id
has_many :settings, :foreign_key => :user_id
attr_reader :full_name
class << self
def login(username, password)
encrypted_password = Digest::SHA1.hexdigest(password)
if not User.exists?(:username => username, :encrypted_password => encrypted_password)
user_id = User.id_from_username(username)
update(user_id, :logged_in_at => Time.now, :logged_out_at => 0)
end
end
def logout
update(current_user.id, :logged_out_at => Time.now)
end
def validate_account(username, password, full_name)
if username.empty? or password.empty or full_name.empty?
return 'Please fill in all the fields.'
end
if User.exists?(:username => username)
return 'That username is already in use.'
end
unless username =~ /^\w+$/
return 'Username field should contain only letters, numbers and underscores.'
end
''
end
def create_account(username, password, full_name)
encrypted_password = Digest::SHA1.hexdigest(password)
User.create(:username => username,
:encrypted_password => encrypted_password,
:full_name => full_name,
:logged_in_at => Time.now,
:logged_out_at => 0)
end
def delete_account
current_user.destroy
end
private
def id_from_username(username)
user = where(:username => username).first
user.nil? ? 0 : user.id
end
def current_user
where(:logged_out_at => 0).first
end
end
end
end
SOLUTION
The problem was that the class User was in a module, here's the solution:
factory :user, class: Bluereader::User do
You need to require the rails environment in your spec helper file. Add the following to spec/spec_helper.rb:
require File.expand_path("../../config/environment", __FILE__)
Update
Even if you're not using Rails, you'll still need to require the models in your spec helper.
Taken from the bottom of the question
The problem was that the class User was in a module, here's the solution:
factory :user, class: Bluereader::User do
For anyone clumsy like me, you may have FactoryGirl in your code where you meant to have FactoryBot

Undefined method `heade' for DealerDetail:Class (NoMethodError)

I am having trouble when running this, I keep getting error
.rb:45:in <main>': undefined method heade' for DealerDetail:Class (NoMethodError)
What am I doing wrong I have looked around but cant find any solutions help will be greatly appreciated
require 'watir-webdriver'
#browser = Watir::Browser.new
#page = [:dealerdetail => "www.google.com",
:findadealer => "www.google.com",
:findadealer_results => "www.google.com"
]
class DealerDetail
attr_accessor :browser
def heade
#browser.goto #page [:dealerdetail]
#browser.element(:id, 'mainNav').exists?
puts 'main navigation bar appears'
puts 'navigation bar does not appear'
end
def footer
if #browser.element(:id, 'pageFooter').exists?
puts 'footer appears'
elsif
puts 'Footer does not appear'
end
end
end
#deal = DealerDetail .new
#deal.heade
heade method trying to access #page, which in not available inside instance cause you defined it outside the scope.
I suppose you want to define #page instance variable inside class:
require 'watir-webdriver'
class DealerDetail
attr_accessor :browser
def initialize
#browser = Watir::Browser.new
#page = [:dealerdetail => "www.google.com",
:findadealer => "www.google.com",
:findadealer_results => "www.google.com"
]
end
def heade
#browser.goto #page[:dealerdetail]
#browser.element(:id, 'mainNav').exists?
puts 'main navigation bar appears'
puts 'navigation bar does not appear'
end
end
#deal = DealerDetail.new
#deal.heade
Also make sure you have no spaces between class/object and called method.
DealerDetail .new should be DealerDetail.new
#page [:dealerdetail] should be #page[:dealerdetail]

You have a nil object when you didn't expect it

I’m interested in the topic of Rails security and using Security on Rails. I'm on Implementing RBAC /page 142/ and i cannot get past the error in the subject.
Here is the code:
module RoleBasedControllerAuthorization
def self.included(base)
base.extend(AuthorizationClassMethods)
end
def authorization_filter
user = User.find(:first,
:conditions => ["id = ?", session[:user_id]])
action_name = request.parameters[:action].to_sym
action_roles = self.class.access_list[action_name]
if action_roles.nil?
logger.error "You must provide a roles declaration\
or add skip_before_filter :authorization_filter to\
the beginning of #{self}."
redirect_to :controller => 'root', :action => 'index'
return false
elsif action_roles.include? user.role.name.to_sym
return true
else
logger.info "#{user.user_name} (role: #{user.role.name}) attempted to access\
#{self.class}##{action_name} without the proper permissions."
flash[:notice] = "Not authorized!"
redirect_to :controller => 'root', :action => 'index'
return false
end
end
end
module AuthorizationClassMethods
def self.extended(base)
class << base
#access_list = {}
attr_reader :access_list
end
end
def roles(*roles)
#roles = roles
end
def method_added(method)
logger.debug "#{caller[0].inspect}"
logger.debug "#{method.inspect}"
#access_list[method] = #roles
end
end
And #access_list[method] = #roles line throwing following exception:
ActionController::RoutingError (You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]=):
app/security/role_based_controller_authorization.rb:66:in `method_added'
app/controllers/application_controller.rb:5:in `<class:ApplicationController>'
app/controllers/application_controller.rb:1:in `<top (required)>'
app/controllers/home_controller.rb:1:in `<top (required)>'
I'm using Rails 3.0.3 and Ruby 1.9.2. I'm storing session in database. In finally thank you for every advise.
It seems like you can't access #access_list in method_added. I would try
class << base
attr_accessor :access_list
#access_list = {}
end
Might not solve your particular problem, but otherwise you won't be able to call #access_list[method] = #roles if your access_list attribute is read-only.
I'm not sure if this is the problem, but this looks suspicious:
class << base
#access_list = {}
attr_reader :access_list
end
Shouldn't #access_list be a class variable ##access_list?
Your defining #access_list as a instance variable of the class but your accessing it in as a instance_variable of an instance of the class. The following should probably work:
module AuthorizationClassMethods
def access_list
#access_list ||={}
end
def method_added(method)
logger.debug "#{caller[0].inspect}"
logger.debug "#{method.inspect}"
access_list[method] = #roles
end
end
If you need Auhorization you might want to check out Cancan by Ryan Bates
https://github.com/ryanb/cancan

Resources