我在attempts
类型的数据库中有一个属性integer
(初始值为0)
当我执行@user.attempts += 1
时,它会抛出TypeError: can't convert Fixnum into String
因此,我得出结论,rails不会根据数据类型自动转换属性。
当我这样做时
@user.attempts.to_i +=1
它抛出NoMethodError: undefined method 'to_i=' for "0":String
当我这样做时,
@user.attempts.to_i = @user.attempts.to_i + 1
它再次抛出NoMethodError: undefined method 'to_i=' for "0":String
。
而且,
@user.attempts = @user.attempts.to_i + 1
工作正常。
我认为原因是,当我执行@user.attempts.to_i + 1
时,它实际上会更改左侧的@user.attempts
。
有人可以对这种行为有所了解吗?
编辑
迁移
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :email_pass
t.integer :attempts
t.timestamps
end
end
end
创建表脚本
-- Table: users
-- DROP TABLE users;
CREATE TABLE users
(
id serial NOT NULL,
email character varying(255),
email_pass character varying(255),
attempts character varying(255),
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
CONSTRAINT users_pkey PRIMARY KEY (id )
)
WITH (
OIDS=FALSE
);
ALTER TABLE users
OWNER TO jashwant;
我在db attempts
中看到的是字符类型。
那么,改变其数据类型的正确方法应该是什么。 我也提出了我的第一个问题,那是什么类型转换的原因?
答案 0 :(得分:2)
在迁移中使用change_column:
rails g migration change_attempts_to_integer_for_users
...
打开并修改迁移
def self.up
change_column(:users, :attempts, :integer)
end
def self.down
change_column(:users, :attempts, :text)
end
运行迁移。
答案 1 :(得分:1)
当你像这样使用+=
时:
something += 1
它与:
相同something = something + 1
当你这样做时,
obj.method = val
它与:
相同obj.method=(val)
因此,您实际上在#to_i=
上调用了@user.attempts
不存在的内容。
执行@user.attempts = @user.attempts.to_i + 1
时,您的通话与此通话相同:
@user.attempts=(@user.attempts.to_i + 1)
存在,因此工作正常。