Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using ActiveRecord in a stand alone script can't update the value #3635

Closed
Zhengquan opened this issue Nov 15, 2011 · 7 comments
Closed

Using ActiveRecord in a stand alone script can't update the value #3635

Zhengquan opened this issue Nov 15, 2011 · 7 comments

Comments

@Zhengquan
Copy link

The former talks about this issue can be found at StackOverFlow
I used ActiveRecord in a stand alone script without rails runner.

The Environment is listed below.

rails:3.1.1
ActiveRecord:3.1.1

Source Code:

require 'rubygems'
require 'logger'
require 'yaml'
require 'uuidtools'
require 'active_record'

module Extensions
  module UUID
    extend ActiveSupport::Concern
    included do
      set_primary_key 'id'
    end
  end
end

ActiveRecord::Base.logger = Logger.new(STDERR)

#the connection config
$archieve_config = {
  :adapter => "mysql2",
  :host => "localhost",
  :username => "root",
  :password => "password",
  :database => "database"
}

module Archieve
  class Answer < ActiveRecord::Base
    establish_connection $archieve_config
    attr_accessible :id, :content
    include Extensions::UUID
  end
end

Archieve::Answer.find_each do |answer|
  str = answer.content
  str.gsub!(/引用:原帖由[\s\S]+发表/,"")
  str.strip!
  #answer.update_attribute(:content, str)
  answer.reload
  answer.update_attributes(:content => str)
end

The table answers only has one record,the table dump file is pushed here.
Mysql Dump File

Prbolem

When I only use update_attribute, It can't update the record.
But when I replace this line with
answer.reload
answer.update_attributes(:content => str)

It indeed can update this only one record.
Is it a bug in ActiveRecord when using it stand alone.

@qoobaa
Copy link
Contributor

qoobaa commented Nov 27, 2011

It works well on sqlite3. Unfortunately I don't have mysql installed currently to check it.

@arunagw
Copy link
Member

arunagw commented Dec 9, 2011

Guys can you confirm this issue??

@Zhengquan
Copy link
Author

you can try to reproduce the issue by the mysqldump file and the ruby script.

@steveklabnik
Copy link
Member

Do you know if this still happens on 3.2? I don't have MySQL installed at the moment, if you can't check it out, I'll install it and give it a go.

@steveklabnik
Copy link
Member

I tried to reproduce this today, and this is what I got:

$ ruby script.rb
DEPRECATION WARNING: Calling set_primary_key is deprecated. Please use `self.primary_key = 'the_name'` instead. (called from block in <module:UUID> at script.rb:12)
D, [2012-09-14T18:16:23.537085 #34549] DEBUG -- :   Archieve::Answer Load (0.8ms)  SELECT `answers`.* FROM `answers` WHERE (`answers`.`id` >= 0) ORDER BY `answers`.`id` ASC LIMIT 1000
D, [2012-09-14T18:16:23.565698 #34549] DEBUG -- :   Archieve::Answer Load (0.4ms)  SELECT `answers`.* FROM `answers` WHERE `answers`.`id` = 1454130827364005 LIMIT 1
D, [2012-09-14T18:16:23.566276 #34549] DEBUG -- :    (0.1ms)  BEGIN
D, [2012-09-14T18:16:23.568821 #34549] DEBUG -- :    (0.4ms)  UPDATE `answers` SET `content` = '一直用着多普达的S1,现在想换换,大家推荐一款智能手机吧,要行货,价位在2K的,谢谢! 话费能报销么?如果每个月能报销100-200的,都值得零元或低价购台iphone4合约机的', `updated_at` = '2012-09-14 18:16:23' WHERE `answers`.`id` = 1454130827364005
D, [2012-09-14T18:16:23.569521 #34549] DEBUG -- :    (0.4ms)  COMMIT

If I comment out the reload and the update_attributes, I get this:

$ ruby script.rb
DEPRECATION WARNING: Calling set_primary_key is deprecated. Please use `self.primary_key = 'the_name'` instead. (called from block in <module:UUID> at script.rb:12)
D, [2012-09-14T18:20:10.968534 #34630] DEBUG -- :   Archieve::Answer Load (0.8ms)  SELECT `answers`.* FROM `answers` WHERE (`answers`.`id` >= 0) ORDER BY `answers`.`id` ASC LIMIT 1000
D, [2012-09-14T18:20:10.982405 #34630] DEBUG -- :    (0.2ms)  BEGIN
D, [2012-09-14T18:20:10.983162 #34630] DEBUG -- :    (0.1ms)  COMMIT

This is with Rails 3.2.8.

So it would appear that this is an issue, yes.

@jonleighton @tenderlove any thoughts?

@senny
Copy link
Member

senny commented Mar 7, 2013

I don't think this is an issue. I guess the problem is that the strings are modified in place using ! methods. I created a standalone script that reproduces the issue:

# -*- coding: utf-8 -*-
require 'active_record'

ActiveRecord::Base.logger = Logger.new(STDERR)
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
  create_table :answers do |t|
    t.text :content
  end
end

class Answer < ActiveRecord::Base; end

Answer.create! content: "Some Content   "

Answer.find_each do |answer|
  str = answer.content

  str.strip!
  # str = str.strip # this works

  answer.update_attributes(:content => str)
end

If you use str = str.strip in place of strip! it updates correctly. The problem is that strip! will modify the version String that is held by the AR instance answer. When update attributes is called AR compares the string to only update the changed fields. Using strip! the fields are equal and hence no update.

@senny
Copy link
Member

senny commented Mar 9, 2013

I'm closing this issue because I don't think it is a bug.

@Zhengquan If my previous response was not the source of the problem, please comment and I'll reopen.

@senny senny closed this as completed Mar 9, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants