Set table name dynamically, a bug? - ruby-on-rails

database.yml looks like
development:
adapter: mysql2
host: localhost
database: database1
username: root
password:
external:
adapter: mysql2
host: localhost
database: database2
username: root
password:
I have a class ExternalDatabaseConnection
class ExternalDatabaseConnection < ActiveRecord::Base
self.abstract_class = true
establish_connection(:external) #connect to external DB specified in database.yml
attr_protected
end
I'm using AR to query on my external DB.
database2(external DB) is set dynamically from user end and I will not have any information about the tables and attributes.
database1(internal DB) which contains information about tables and some attributes.
So basically I have to handle things dynamically.
Works fine.
ExternalDatabaseConnection.table_name = "set_table1" #dynamic
ExternalDatabaseConnection.create(...) #creates a record.
This doesn't.
ExternalDatabaseConnection.table_name = "set_different_table" #dynamic
ExternalDatabaseConnection.create(...)
throws
unknown attribute: attribute_name
Both the things happen in loop, so every-time it works good for initial table set, for the second table, it throws an error.
Debugging:
Note:
ExternalDatabaseConnection.table_name = "payments"
ExternalDatabaseConnection.column_names
=> ["id", "customer_id", "patent_id", "amount", "currency", "date"]
ExternalDatabaseConnection.table_name = "patents"
=> "patents"
2.0.0-p451 :006 > ExternalDatabaseConnection.column_names
=> ["id", "customer_id", "patent_id", "amount", "currency", "date"]
ExternalDatabaseConnection.all
ExternalDatabaseConnection Load (0.4ms) SELECT `patents`.* FROM `patents`
=> [#<ExternalDatabaseConnection id: 1, number: "1111", description: "https://www.google.co.in", registry_date: "2014-08-20", documnetdir: nil, currency: #<BigDecimal:a8f2adc,'0.1212E2',18(27)>>, #<ExternalDatabaseConnection id: 4, number: "1", description: "jhufgtrdfyuh", registry_date: nil, documnetdir: "", currency: #<BigDecimal:a8f2258,'0.0',9(18)>>, ....]
There is no change in attributes, may be this is causing a problem.
If any information is missing, comment up.
ruby 2.0.0p451
Rails 3.2.17
edit1:
Tries:
Before setting table name
1) ExternalDatabaseConnection.table_name = nil .
2) ExternalDatabaseConnection.clear_active_connections! and clear_all_connections!
3) tried with set_table_name :table1
edit2:
ClassName.column_names is not getting changed even after setting different table_name for the Class

I have tried this following way. It may help
:set_table_name method is used to change the table name dynamically. You can set the table name and get the attributes name instead of columns name.
For payments table
ExternalDatabaseConnection.set_table_name :payments
ExternalDatabaseConnection.first.attribute_names
Then you have to reset the column information
ExternalDatabaseConnection.reset_column_information
For patents:
ExternalDatabaseConnection.set_table_name :patents
ExternalDatabaseConnection.first.attribute_names

Related

Rails: Active Record Timeout

This is a piece of code in place. When I add this to the cron with timeout the entire array gets saved twice. When I remove timeout nothing gets saved
In this scenario we would want to save the array results (coming in from an api) with over 100k records to be saved to the db. I have used bulk insert and TinyTds gems here
ActiveRecord::Base.establish_connection(adapter: 'sqlserver', host: "xxx", username: "xxx", password: "xxx", database: "xxx", azure: true, port: 1433, timeout: 5000)
class Report < ActiveRecord::Base
self.primary_key = 'id'
end
my_array = [] #count of 100000 records
Report.bulk_insert(:account_owner_id) do |worker|
my_array.drop(2).each do |arr|
worker.add account_owner_id: arr[0]
end
end
You can try removing timeout and adding ignore: true to your bulk insert as shown here. There may be an insert that is failing.
Report.bulk_insert(:account_owner_id, ignore: true) do |worker|

Rails4 charset issue when connect to remote MySQL DB

I use next settings to connect to remote DB:
class MyModel < ActiveRecord::Base
self.table_name = 'users'
establish_connection(
adapter: "mysql2",
host: "host_ip",
encoding: "koi8u",
username: "custom_name",
password: "password",
database: "db_name")
end
It connects well but when I make a query, I receive something like Address: "п⌠п╟п╪п╟п?п╦п? п░п╩я▄я├п╣я│я┌"
I also try another variant of connection like:
connection = Mysql2::Client.new( host: 'host_name',
username: 'user',
password: 'password',
port: 3306,
database: 'db_name',
encoding: 'koi8u',
reconnect: true
)
In this case I receive connection object, but can't make a query... When I use
connection.query("SELECT * FROM users") it returns me the connection object...
Also when I check encoding it returns:
MyModel.first.Address.encoding.name
MyModel Load (6.8ms) SELECT `users`.* FROM `users` ORDER BY `users`.`login` ASC LIMIT
1
=> "UTF-8"
When in settings I use koi8u !
I was checking charset on MySQL server in this DB - it is set to koi8u !
Any ideas? I need to connect to this DB with normal charset
It seems to me that your database locale is different then you expect it to be
Did you changed it or set it in any stage?
It is not enough to declare about it in the connection string
You can find up here how to check what is your database character set
How do I see what character set a MySQL database / table / column is?

Mysql2::Error: Incorrect date value: '--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess

I moved from sqllite to mysql (recreated the same workspace with mysql right from the beginning. Did not do any migrations).
The code worked well with sqllite but is erroring out with mysql. This is how my database.yml looks like:
development:
adapter: mysql2
database: dev
username: root
password:
host: localhost
pool: 5
My code takes in a date through a date select in the view:
<%= date_select(:dob, NIL, :use_short_month => true, :start_year => Time.now.year - 100,
:end_year => Time.now.year, :order => [:day, :month, :year]) %>
The model looks like this:
t.string "firstName"
t.string "lastName"
t.string "Email"
t.string "password"
t.date "dob"
But the insert through the following code in the controller fails:
#user.dob = params[:dob]
This is the error I get:
Mysql2::Error: Incorrect date value: '--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
(1i): '2013'
(2i): '4'
(3i): '18'
' for column 'dob' at row 1: INSERT INTO `users` (`Email`, `created_at`, `dob`, `firstName`, `lastName`, `password`, `personalEmail`, `updated_at`) VALUES ('abc#xyz.com', '2013-04-18 15:46:26', '--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n(1i): \'2013\'\n(2i): \'4\'\n(3i): \'18\'\n', 'ABC', 'XYZ', 22, NULL, 'ab4d8d2a5f480a137067da17100271cd176607a1', '2013-04-18 15:46:26')
I had googled quite an extent but couldnt find any references to this. Appreciate any leads or help on this.
the problem is the multiparameter thing. rails date_select helper generates 3 dropdowns which pass 3 different parameters to your controller. if you use mass assignment in your controller, rails magically converts these 3 values to 1 date value. this (quite old) blog post shows a way to do it without mass-assignment: http://www.springenwerk.com/2008/05/set-date-attribute-from-dateselect.html
but, this post is rather old, and there could(!) be a better way by now
Whats clear to me is that the dat object is not formatted correctly for the mysql database. Try something like
#user.dob = params[:dob].to_date
Try formatting the date object in different ways to see what works. It may also help to open up rails console and try working things out manually. Let me know how that goes.
-Brian

Rake Unit Testing : "False" being used for column "no"

Post :: Model
class Post < ActiveRecord::Base
attr_accessible :body, :name, :no, :num
end
Posts.yml under (test/fixtures/)
one:
name: MyString
body: MyString
no: 1
num: 2
On running, rake test:units, the following stack trace is generated
Error:
test_Post_for_correct_attributes(PostTest):
ActiveRecord::StatementInvalid: SQLite3::SQLException: table posts has no column named false: INSERT INTO "posts" ("name", "body", "false", "num", "created_at", "updated_at", "id") VALUES ('MyString', 'MyString', 1, 2, '2012-12-26 10:24:36', '2012-12-26 10:24:36', 980190962)
Now, here - the table field 'no' has been converted to 'false'. (which seems to be a problem since its being interpreted as FALSE and not as a object variable)
A bug with how it is converting the variables from yaml to object?
Rails version Rails 3.2.9 and Ruby ruby 1.9.3p194
That seems like bug to me since Rails should be able to pick up on that, especially since this is autogenerated. Anyway, as a temporary workout, you can use:
one:
name: MyString
body: MyString
"no": 1
num: 2

Error building doctrine model

I use symfony in version 1.4.9 with doctrine.
symfony doctrine:build-schema works and create a schema in config/doctrine/schema.yml
symfony doctrine:build-model fails with the following message:
>> doctrine generating model classes
>> file+ /tmp/doctrine_schema_92251.yml
Invalid schema element named "class" at path "doctrine"
the tmp/doctrine_schema_922... is this:
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=xxxxx'
username: xxxxx
password: xxxxx
attributes:
use_dql_callbacks: true
use_native_enum: true
Products:
connection: doctrine
tableName: products
columns:
product_id:
type: integer
...
any ideas whats wrong?
I don't think the first section of your schema is valid, I have never seen this before.
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=xxxxx'
username: xxxxx
password: xxxxx
attributes:
use_dql_callbacks: true
use_native_enum: true
The database connection string should go in your database.yml file. In fact, this whole section resembles something that would go in the database.yml file. The remaining code in your schema looks good.

Resources