Ruby/ActiveRecord not detecting changes after stripping whitespace from field - mysql

I am trying to remove whitespace and carriage returns from various fields in a MySQL database using the mysql2 adapter and ActiveRecord:
Ruby 1.9.3p194
ActiveRecord 3.2.8
MySQL 5.5.28
foo = People.find(1)
foo.name => "\rJohn Jones"
foo.name.lstrip! => "John Jones"
foo.name => "John Jones"
foo.changes => {} #no changes detected to foo.name???
foo.save => true # but does nothing to database.
if I do:
foo.name = "John Jones"
foo.save => true
People.find(1).name => "John Jones" # this works and saves to database
I've searched all over for this... any suggestions?

When you do in-place modifications on model attributes, no assignment occurs and the model is unaware any changes have been made. The correct way to do this is to reassign:
foo.name = foo.name.lstrip
This triggers the name= method and the dirty tracking is engaged.

Related

Ruby Mysql2 Client not taking backslash while insert

We are using production and staging databases in our application.
Our requirement is to insert all the records to staging database when ever a record is added in production database, so that both the servers are consistent and same data.
I have used Mysql2 client pool to connect to staging server and insert the record that is added to production.
here is my code:
def create
#aperson = Person.new
#person = #aperson.save
if #person && Rails.env == "production"
#add_new_person_to_staging
client = Mysql2::Client.new(:host => dbconfig[:host], :username => dbconfig[:username], :password => dbconfig[:password], :database => dbconfig[:database])
#person_result = client.query('INSERT INTO user_types(user_name, regex, code) Values ("myname" , "\.myregex\." , "ns" );')
end
end
Here "#person_result" record is inserted to mysql table but the "regex" column eliminates "\" slashes.
like : user_name = myname, regex = .myregex., code = ns
when I manually execute the "Insert" query in mysql command line it inserts as it is along with \ slash. but not through "client.query"
Why does \ slash is eliminated. please help me here.
Thanks.
\ is likely being removed by the MySQL2 client as part of a SQL injection protection preprocessor.
Have you looked at trying either a double backslash or using the escape method to properly escape the string?
Try using this
#person_result = client.query('INSERT INTO user_types(user_name, regex, code) Values (myname , "\."+myregx+".\" , ns )')

Datamapper not saving records to MySQL

Datamapper isn't saving my user models.
(This is a Sinatra webapp and the db is an AWS RDS mysql db.)
The User model:
class User
include DataMapper::Resource
property :uid, Serial
property :user, String, :key => true, :length => 3..20
property :pass, String, :required => true, :length => 6..50
end
The code to set it:
post "/register" do
username = params["username"]
password = params["password"]
begin
encrypted_password = BCrypt::Password.create password
meme = User.new :user => username, :pass => encrypted_password
meme.save
raise DatabaseError, "User record not saved" unless meme.saved?
flash[:register] = "Welcome, new user! Please log in now."
redirect "/login"
# disabled rescue stuff...
end
end
(if you want, test it yourself at dittoslash.uk)
(can i do this on stack overflow? edit this out if you can't)
EDIT: Updated validation rules. Now I'm getting an error of 'Pass must be between 6 and 50 characters long' (with a 28 (or 30?) character password)
max pleaner answered this for me.
For Googlers looking for answers:
check your validations, and make sure that encryption dosen't make the password longer than your maximum.

Encoding latin1 to UTF8 in Rails

I have a legacy MySQL database with latin1 encoding, and new MySQL database with utf-8 encoding. When I migrate the data from the legacy to new one, the strings returned and rendered in webpages contains weird characters.
example: â¥Chocolate biscuitâ¢
There's a model that connects to the old database to get the records, and use a rake task to map the old records and create new records
class LegacyDatabase < ActiveRecord::Base
self.abstract_class = true
establish_connection(
adapter: "mysql2",
database: "old_database",
encoding: "latin1"
)
end
I referred to this website to solve the encoding problems, but the fallback hash is hardcoded. I need a dynamic one so that I don't need to add the fallbacks each time when a loop that fixes encoding is called.
def fix_encoding(str)
# Referring to the solution from the website
new_str = str.encode('cp1252',:fallback => {
"\u0080" => "\x80".force_encoding("cp1252"),
"\u0081" => "\x81".force_encoding("cp1252"),
"\u008D" => "\x8D".force_encoding("cp1252"),
"\u008F" => "\x8F".force_encoding("cp1252"),
"\u0090" => "\x90".force_encoding("cp1252"),
"\u009D" => "\x9D".force_encoding("cp1252"),
"\u0098" => "\x98".force_encoding("cp1252"),
"\u0099" => "\x99".force_encoding("cp1252")
}).force_encoding("utf-8")
return new_str
end
I want to change it to be dynamic, but I failed to convert it.
# How to do it in dynamic?
new_str = str.encode('cp1252', :fallback => Proc.new { |v| "#{v[4..5]}".force_encoding("cp1252") }).force_encoding("utf-8")
Or is there any other solution to fix the encoding problem?

Rails4, MySql, mysql2 encoding issue

I have a project where Rails 4, MySql 5.1, gem mysql2 are used.
This stack worked fine until today. I've added two fields in a table (added corresponding migration) and if I save data to the table, the data in this field will look ugly, like -%D0%9D%D0%BE%D0%B4%D0%B0%D1%80%D0%B8
Here is Rails log:
This is the data from a request. All looks fine, 'name' and 'comment' are in Russian.
Parameters: {"{\"user_id\":\"1\",\"name\":\"АБВ\",\"email\":\"mike#outofcloud.ru\",\"answer\":\"5\",\"comment\":\"цувцув\"}"=>nil}
But in the SQL statement the 'name' parameter changed:
SQL (23.3ms) INSERT INTO "feedbacks" ("answer", "code", "comment", "created_at", "email", "name", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["answer", 5], ["code", 1], ["comment", "цувцув"], ["created_at", "2015-05-13 08:54:22.047321"], ["email", "example#example.ru"], ["name", **"%D0%90%D0%91%D0%92"**], ["updated_at", "2015-05-13 08:54:22.047321"], ["user_id", "1"]]
'comment' field was added before my migrations, it works as expected. It look great in the DB and in the app.
'name' field have been added recently and its doesn't work as expected.
Can someone help with the issue?
The string that you're showing is the result of using URI.encode on "АБВ" - see:
[4] pry(main)> URI.encode "АБВ"
=> "%D0%90%D0%91%D0%92"
Rails doesn't do this by itself. You must have some code somewhere else (or, hopefully not, a gem) that's performing that transformation.
If you don't know where that is then please add the code from your controllers showing any before_action methods, or other transformations. Also the code from your model if you're doing anything before_save or any custom attribute setters, eg. def name=

Ruby + mysql2 querying fails with variables

Working with Ruby 2.0, Qt4 gem and Mysql2 gem. I need to compare the text of two lineedit and make a query with them, which is a failure so far.
client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => "123456", :database => "school")
# text of both lineedits saved into local variables
tName=#leName.text()
tPass=#lePass.text()
#then
res= client.query("SELECT usr_name, usr_pass, usr_tipo FROM user WHERE usr_name = tName AND usr_pass = tPass")
The only thing that fails is that query. I've tried to put the local variable as global (#tName, #tPass), or put them into #{}, which search for columns in the table user named tName and tPass, also tried to put them into '' but that only search for a user named tName.
I want the query to search for usr_name= "text inside tName". What am I doing wrong?
EDIT: if you are wondering, tName, tPass are strings and the fields usr_name and usr_pass are varchar(50).
Looks like you didn't interpolate the variables. do the following
res= client.query("SELECT usr_name, usr_pass, usr_tipo
FROM user
WHERE usr_name = '#{tName}' AND usr_pass = '#{tPass}'")