How to define variable outside method that is present inside method? - mysql

I'm trying to create a method that allows me to query SQL in ruby without typing results = client.query('code') for every query. Heres my current method but it says that results are undefined in my puts statement. When I don't use my method it works normally.
require "mysql2"
client = Mysql2::Client.new(:username => 'buck19j')
def sql(code)
client = Mysql2::Client.new(:username => 'buck19j')
results = client.query(code)
end
sql('SHOW DATABASES')
puts(results.to_a)
How to define variable outside method that is present inside method?

Make the method return the value, not assign it:
def sql(code)
client = Mysql2::Client.new(:username => 'buck19j')
client.query(code)
end
Then assign a variable when you call the method:
results = sql('SHOW DATABASES')
puts(results.to_a)

results doesn't "go out" the sql method, because is a local variable. An approach would be to define it as an instance variable, and you could use then as you do with puts (still unclear what's the whole context of this).
def sql(code)
client = Mysql2::Client.new(:username => 'buck19j')
#results = client.query(code)
end
sql('SHOW DATABASES')
puts(#results.to_a)
Other way would be just leave the function returns the client.query(code) value:
def sql(code)
client = Mysql2::Client.new(:username => 'buck19j')
client.query(code)
end
puts(sql('SHOW DATABASES').to_a)

Related

select within uncached block is returning a stale object

I am doing something like the following.
class SomeModel
def crazy
sm = SomeModel.where(:id => 1).first
sleep(30)
# after 15 seconds we update the record manually
sm = SomeModel.uncached {SomeModel.where(:id => 1).first}
begin
sm.field = 'value'
sm.save
rescue ActiveRecord::StaleObjectError => e
puts 'happening'
end
end
end
When this model method is called from a controller, as the uncached select is performed after the manual update, I should not be getting a stale object but testing it says otherwise. Am I misunderstanding something? I am using Rails 3.0.5 with Mysql.

rails 2.3 convert hash into mysql query

I'm trying to find out how rails converts a hash such as (This is an example please do not take this literally I threw something together to get the concept by I know this query is the same as User.find(1)):
{
:select => "users.*",
:conditions => "users.id = 1",
:order => "username"
}
Into:
SELECT users.* FROM users where users.id = 1 ORDER BY username
The closest thing I can find is ActiveRecord::Base#find_every
def find_every(options)
begin
case from = options[:from]
when Symbol
instantiate_collection(get(from, options[:params]))
when String
path = "#{from}#{query_string(options[:params])}"
instantiate_collection(format.decode(connection.get(path, headers).body) || [])
else
prefix_options, query_options = split_options(options[:params])
path = collection_path(prefix_options, query_options)
instantiate_collection( (format.decode(connection.get(path, headers).body) || []), prefix_options )
end
rescue ActiveResource::ResourceNotFound
# Swallowing ResourceNotFound exceptions and return nil - as per
# ActiveRecord.
nil
end
end
I'm unsure as to how to modify this to just return what the raw mysql statement would be.
So after a few hours of digging I came up with an answer although its not great.
class ActiveRecord::Base
def self._get_finder_options options
_get_construct_finder_sql(options)
end
private
def self._get_construct_finder_sql(options)
return (construct_finder_sql(options).inspect)
end
end
adding this as an extension gives you a publicly accessible method _get_finder_options which returns the raw sql statement.
In my case this is for a complex query to be wrapped as so
SELECT COUNT(*) as count FROM (INSERT_QUERY) as count_table
So that I could still use this with the will_paginate gem. This has only been tested in my current project so if you are trying to replicate please keep that in mind.

why pageObject based on Cheezy does not work?

I'm new to ruby (1.9.3)
I have intermediate experience with Selenium WebDriver plus C#. I want to move to Watir-Webdriver.
I'd be grateful to find out why the first block of IRB code works, but the second block simply loads the correct page, then does nothing. The page is active and responds to manual input.
The second block of code is based on the PageObject example here:
https://github.com/cheezy/page-object/wiki/Get-me-started-right-now%21
require 'watir-webdriver'
browser = Watir::Browser.start 'http://x.com/'
browser.select_list(:id, "ddlInterestType").select("Deferred")
browser.select_list(:id, "ddlCompanyName").select("XYZ")
browser.button(:value,"Enter Transactions").click
Second block
require 'watir-webdriver'
browser = Watir::Browser.new :firefox
browser.goto "http://x.com/"
deferredPage = DeferredPage.new(browser)
deferredPage.interestType.select = 'Deferred'
deferredPage.company.select = 'XYZ'
deferredPage.enterTransactions
class DeferredPage
include PageObject
select_list(:interestType, :id => 'ddlInterestType')
select_list(:company, :id => 'ddlCompanyName')
button(:enterTransactions, :id => 'btnEnterTransactions')
end
In your page-object code example, after loading the page, an exception is likely being thrown (which makes it seem like nothing happens). That code should throw an no method exception:
undefined method `select=' for "stuff":String
When you declare a select list there are three methods created:
your_select= - this is for setting the select list
your_select - this is for getting the select list value
your_select_element - this is for getting the page-object gem element
When you do deferredPage.interestType, it returns a string that is the value of the select list. Strings do not have a select= method, which is why you get the exception (and does nothing).
The two selections should be done without the .select:
deferredPage.interestType = 'Deferred'
deferredPage.company = 'XYZ'
As you can see the page-object API is slightly different than the watir API.
While googling for info on page objects, I found this page by Alister Scott. :
http://watirmelon.com/2012/06/04/roll-your-own-page-objects/
For an idiot++ such as me, I think I'll use his method until I know more about Watir-Webdriver. Based on #justinko's comment, I'll stick to one API for the present. I tried rolling my own, and it works fine:
require 'watir-webdriver'
browser = Watir::Browser.new :ie
class DeferredPage
def initialize( browser )
#browser = browser
end
def enterIntType(intType)
#browser.select_list(:id, "ddlInterestType").select(intType)
end
def clickEnter()
#browser.button(:value,"Enter Transactions").click
end
end
dp = DeferredPage.new(browser)
browser.goto "http://x.com"
dp.enterIntType( "Deferred" )
dp.clickEnter
Could you please let us know what error you are getting? I suspect the problem you are seeing is related to the way the Ruby interpreter reads the code. It reads the file from top to bottom and you are using the DeferredPage class before it is defined. What would happen if you changed your code to this:
require 'watir-webdriver'
require 'page-object'
browser = Watir::Browser.new :firefox
class DeferredPage
include PageObject
select_list(:interestType, :id => 'ddlInterestType')
select_list(:company, :id => 'ddlCompanyName')
button(:enterTransactions, :id => 'btnEnterTransactions')
end
deferredPage = DeferredPage.new(browser)
deferredPage.navigate_to "http://x.com/"
deferredPage.interestType = 'Deferred'
deferredPage.company = 'XYZ'
deferredPage.enterTransactions
In this case I am declaring the class prior to using it.
Another thing I might suggest is creating a higher level method to perform the data entry. For example, you could change your code to this:
require 'watir-webdriver'
require 'page-object'
browser = Watir::Browser.new :firefox
class DeferredPage
include PageObject
select_list(:interestType, :id => 'ddlInterestType')
select_list(:company, :id => 'ddlCompanyName')
button(:enterTransactions, :id => 'btnEnterTransactions')
def do_something(interest, company)
self.interestType = interest
self.company = company
enterTransactions
end
end
deferredPage = DeferredPage.new(browser)
deferredPage.navigate_to "http://x.com/"
deferredPage.do_someting('Deferred', 'XYZ')
This is cleaner - the access to the page is abstracted behind a method that should add some business value.
-Cheezy

How should I write case statement depend of parameters key?

For example I have index action:
def index
if params[:query]
#pharmaceutics = Pharmaceutic.where("name LIKE ?", params[:query])
elsif params[:code]
#pharmaceutics = Pharmaceutic.where("barcode LIKE ?", params[:code])
else
#pharmaceutics = Pharmaceutic.all
end
end
And when I send two params: code and query I would like to filter my Pharmaceutics using both of them. I have MySQL database.
I would probably use scoped method, like this:
def index
scope = Pharmaceutic.scoped # Pharmaceutic.all if you use Rails 4
scope = scope.where('name LIKE ?', params[:query]) if params[:query].present?
scope = scope.where('barcode LIKE ?', params[:code]) if params[:code].present?
#pharmaceutics = scope
end
You can also write your custom scopes and replace where(...) with them to make the code clearer.

Help building up LINQ query when using anonymous types

I've started out with:
IQueryable<Author> authors2 = db.Authors;
Then I build up authors2 in multiple if statements, here's one of them
authors2 = authors2.Where(t => t.ItemAuthors.Any(b => b.Item.CategoryItems.Any(z => z.categoryID == int.Parse(ddlCategory.SelectedValue))));
Then finally I would like to append this to the end of the built up where clauses
authors2.OrderBy(x => x.text).Select(x => new
{
authorText = string.Format("{0} ({1})",x.text, x.ItemAuthors.Count())
});
To bind a control like this:
ddlAuthor.DataSource = authors2;
ddlAuthor.DataTextField = "authorText";
ddlAuthor.DataBind();
Apparently the compiler is not very happy about my select new statement. How can I rewrite this to achieve the same goal? I believe this is called creating an anonymous type.
It says an explicit conversion exists(are you missing a cast?) I can't figure out how to cast it.
In your third statement, the returned type is not same as authors2 because the Select projects a different type other than Author
So assign the value to a new variable
var authorsFinal = authors2
.OrderBy(x => x.text)
.Select(x => new
{
authorText = string.Format("{0} ({1})",
x.text,
x.ItemAuthors.Count())
});