Rails model not syncing properly with database - mysql

I have a rails model called Merchant with attributes name and id. I am having an issue where rails and my database disagree on a certain Merchant's name.
This is what's happening from rails:
1.9.2p320 :001 > Merchant.where(:id=>550).count
=> 1
1.9.2p320 :002 > Merchant.where(:id=>550).first.name
=> nil
And this is what's happening from mysql:
mysql> SELECT name FROM merchants WHERE id=550;
+----------+
| name |
+----------+
| Testname |
+----------+
1 row in set (0.00 sec)
According to FlyersAdmin::Application.config.database_configuration[::Rails.env] the database being used by rails in my first code window is the same as that being used by mysql in the second window. Why the merchant's name is nil instead of "Testname" is what I'm stumped on.
Worth noting is that recently I updated the database they're both using with new data, is it possible that this is causing the discrepancy? Maybe rails caches data and so hasn't looked at the updated database yet? I'm stumped, any help is appreciated.
EDIT:
Here's another clue to add to the mystery: Running Merchant.where(:name => nil) returns the empty list! Why isn't it picking the Merchant with id 550?

What should be the output of this Merchant.where(:id=>550).first.name?. It is possible you created a Merchant but you just did not define a name, so it got the default value nil

Why you do .first when you select one record anyway?
Merchant.find(550).name
should give you your record.
Try
Merchant.first.name
to get the first record of the model.

Related

What is note-level warning in MySQL?

Okay, I understand what are errors and warnings in the context of MySQL. But what's the need of note-level warning? I have already searched the MySQL documentation but didn't find anything relevant. It would be better if someone could shed some light on the what are they and why they are useful.
mysql> create database if not exists city;
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show warnings
-> ;
+-------+------+------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------+
| Note | 1007 | Can't create database 'city'; database exists |
+-------+------+------------------------------------------------+
1 row in set (0.00 sec)
I've always considered Note to be like an "FYI": something happened, or didn't, that may be of interest. The closest definition I can find in the docs is:
... events that do not affect the integrity of the reload operation
which is from the sql_notes server variable, one perhaps not often used outside of mysqldump.
Trawling through the MySQL source code, looks like Sql_Condition::SL_NOTE annotates warnings of this level. There are a few, but they are mostly as you'd expect for non-impactful information:
Event already exists
Table already exists
Query '%s' rewritten to '%s' by a query rewrite plugin
Password set
Sadly, I would have expected the code docblock to give a little more information about them, but it doesn't:
class Sql_condition {
public:
/**
Enumeration value describing the severity of the condition.
*/
enum enum_severity_level { SL_NOTE, SL_WARNING, SL_ERROR, SEVERITY_END };
This might warrant a documentation bug report to MySQL team.
Interestingly, MariaDB has this to say:
A note is different to a warning in that it only appears if the sql_notes variable is set to 1 (the default), and is not converted to an error if strict mode is enabled.
My takeaway from that, in Maria and possibly by extension MySQL: notes are warnings, but ones that can be ignored because no data-loss or side-effect is described.

How to send and receive raw string from MySQL

I am working on a SQL Developer-like application, in which user enters some SQL command and the result from the server is shown in a <div> on web page.
The problem is that user can enter ANY string, valid SQL or not, for example if an user sends select * from employees; I want to receive and display in
the <div> text EXACTLY as below :
+---------+----------+---------------+----------+
| user_id | username | full_name | password |
+---------+----------+---------------+----------+
| 1 | john | John Doe | admin |
And when he enters a bad SQL string, the <div> message should be the standard MySQL error strings , for example :
mysql> select * from usrsss;
ERROR 1146 (42S02): Table 'mydb.usrsss' doesn't exist
I know about security risk , I do not care about it at this point.
Can this be done, as I have no control on the SQL string syntax being sent by user?
First of all, the prompt you see there mysql> represents the MySQL Shell. This is not SQL or JDBC but a command line interface provided by MySQL.
This MySQL Shell allows you to execute:
SQL statements.
A variety of other statements that are NOT part of SQL.
The JDBC API you want to use will allow you to run the first group of statements -- the SQL statements. Unfortunately, it won't allow you to run the second one, so you are out of luck for this one.
Also, for the first group the JDBC API will provide error codes and error messages that are not exactly the same ones you see when using the MySQL Shell.
Bottom line, you can simulate some of these commands, but it will not be the exact same experience that you probably expect.
However... and this is a big one, why do you want to do this in the first place? One of my developers asked me if he could do this, since it's not difficult to implement; this way we could easily run any SQL command from the web page. Great? Well... no. This is a HUGE SECURITY RISK. If anyone hacks your web page, you would be exposing the whole database.
In other words, don't deploy this code to production.
If you are using java.sql.Connection,
create a statement first by using .createStatement().
use .executeQuery() for searching
and .executeUpdate() for inserts, updates and deletes
When searching identify the number of columns to create a table.
ResultSet rs = statement.executeQuery(String sql);
ResultSetMetaData metaData = rs.getMetaData();
In ResultSetMetaData,
.getColumnCount() will give you the column count.
in a for loop create the columns, while creating .getColumnName(int index) will give you the column name.
After creating the table, iterate the ResultSet,
while (rs.next()) {
rs.getString(int columnIndex);
}
use the above method to get values, and add rows to your table.
Don't forget to surround the code block with
try{
} catch(Exception e){
e.getMessage();
}
so if anything goes wrong you can get the SQLException thrown. That will include a message, the probable cause for the error.
Work your way out... Enjoy!

Issue with ruby ActiveRecord gem

I am using rails 4.2.4 version.
I have a database table 'upload' which has 10000 entries.
file_name | file_path | parent_directory | created_at
I have a model, Upload with following function:
select(:parent_directory).distinct
This should provide me a list of distinct parent directories present in the table.
When I do select(:parent_directory).distinct.size,
it executes select distinct id from upload;
and gives me all 10000 entries, which is wrong.
But when I do select(:parent_directory).distinct.count,
it executes select distinct parent_directory from upload;
and gives me 3000 entries, which is correct.
Is this some kind of issue with ActiveRecord gem or am I doing something wrong here?
There is an open issue regarding this in the rails repo https://github.com/rails/rails/issues/16182.
The problem is with size which is trying to make intelligent choices for you. If you use length instead of size you will have the expected result.

Rails 4. Migrating (some) legacy DB data from old db to rails existing DataBase

I have a task to import old data from old DB to new Rails app. Old program was created in Delphi and is outdated so customer decided create rails app for replacing it. I have dump file, and I am creating local MySQL db now and inserting there data for last 8 years (mysql is working for over an hour already) :)
Now I am not sure about the way old data should be imported. The problem is that old db tables and columns are named differently from what I have in my App and there are many of unused and unneeded columns/tables there. So I need select only some of them and insert into App DB. Could You please suggest the best solution for this case?
Thank you in advance!
You can adjust old db to rails app and work with it
Let's imagine you have old DB with the following table old_posts
old_posts
________________________________________
sysid | name | description |
_______________________________________
| | |
1 | The best post| Some description |
_______________________________________
| | |
2 | Another post| Another descrip |
________________________________________
In rails you can define table_name with
More information in doc:
http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name
Also you can redifine attributes with alias_attribute
More information in doc:
http://api.rubyonrails.org/classes/Module.html#method-i-alias_attribute
To change primary key primary_key
More information in doc:
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html#method-i-primary_key-3D
The example will be seems as
class Post < ActiveRecord::Base
self.primary_key = 'sysid'
self.table_name = 'old_posts`
alias_attribute :name, :title
alias_attribute :description, :content
end
Then you can invoke:
p = Post.find(1)
p.title #= > The best post
Also you can use legacy database separately from rails app database
http://ilikestuffblog.com/2012/09/21/establishing-a-connection-to-a-non-default-database-in-rails-3-2-2/

Zero padding : convert MD-1 to MD-001 with pure sql

guys I need help.
I am using Mysql / phpmyadim.
I have db with table which stores name and code id of people.
+--------+---------+
| Name | code_id |
+--------+---------+
| Nazeer | MD-1 |
+--------+---------+
I have 10 contacts and ids. I am using php program which used to generate automatic code.
recently i imported more records in to db from excel file and record increase to 5000+.
My php automatic code stopped generating codes giving me syntax error on code id.
I figured out that my excel import was having code id like MD-1, MD-2, etc. and my program used automatic code for number in 3 digits since my record is over thousands which 4 digit it give syntax error.
I did some research on solving that and the answer was to change all 2 digit numbers eg. "MD-1" ~ "MD-99" TO "MD-001" ~ "MD-099" and my program will work again.
so the question is how do i do that in phpmyadmin sql to change it. I need to keep 'MD-' and add '0' then add back the corresponding number.
thanks and appreciate your help in advance.
Regrds.
this sql will update all your data, but like I said in comments, you better off fixing your php code instead.
WARNING : this sql only works assuming all your data are in the format of [MD-xxx] with 3 or less numbers in it
UPDATE your_table SET
code_id=case length(substr(code_id,4))
WHEN 1 THEN concat("MD-00",substr(code_id,4))
WHEN 2 THEN concat("MD-0",substr(code_id,4))
ELSE code_id END;
I assume that you want to update the content MD-1 to MD-001 and MD-99 to MD-099. To do that you can write a PHP code to retrieve the rows one by one and have to match patterns and then update. Here are some useful links. link 1
HINT : you can check 5 digit string and then add another 0 in the position of 3.(use [exploid] to split by "-" and then concat with "-0" 2) There are no way to do the same only by using MYSQl since it's not a programming language. And other thing is PHP is not a program. It's a programming language.
run UPDATE query and use CONCAT function :
for ($x=0; $x=<upto>; $x++){
UPDATE <table_name>
SET <columnname>= CONCAT('MD-',0,$x)
WHERE <columnname>= CONCAT('MD-',$x)
}
Below simple update command can help you.
UPDATE mytable
SET code_id=IF(LENGTH(code_id)=4,CONCAT(SUBSTRING_INDEX(code_id,'-',1),'-00',SUBSTRING_INDEX(code_id,'-',-1)),IF(LENGTH(code_id)=5,CONCAT(SUBSTRING_INDEX(code_id,'-',1),'-0',SUBSTRING_INDEX(code_id,'-',-1)),code_id));