我在Ruby中有一个非数据库支持的类:
class User
attr_accessor :countries
end
我希望国家/地区只是一组ISO国家/地区代码(美国,GB,CA,AU等),我不想建立一个单独的模型来保存每个代码。是否有一种神奇的方法可以让Ruby明白:countries
是一个数组并相应地对待它,还是需要编写countries
和countries=
方法?
我尝试使用user.countries = ['US']设置countries数组,并且我得到NoMethodError。
答案 0 :(得分:4)
变量的类型在Ruby中无关紧要。
attr_accessor
只创建设置和返回实例变量的getter和setter方法;在这种情况下@countries
。您可以将实例变量设置为数组,或使用setter:
class User
attr_accessor :countries
def initialize
@countries = %w[Foo Bar Baz]
# Or...
self.countries = %w[Foo Bar Baz]
end
end
> puts User.new.countries
=> ["Foo", "Bar", "Baz"]
我个人更喜欢使用实例变量而不是self.xxx
;忘记self.
位并且最终设置局部变量,留下实例变量nil
太容易了。我也认为这很难看。
如果各国不会在不同实例之间进行更改,为什么不是常数?
编辑/澄清
塔德曼的观点很好,例如,this diatribe on state。我不关心的环节仅限于小型的,自我控制的,独立的课程。在做出这些假设时存在固有的风险,这些风险的程度取决于项目。
答案 1 :(得分:3)
看起来countries
应该是常数:
class User
COUNTRIES = %w(
AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM
BT BO BQ BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL CN CX CC CO KM
CG CD CK CR CI HR CU CW CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI
FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU GT GG GN GW GY HT HM VA HN HK
HU IS IN ID IR IQ IE IM IL IT JM JP JE JO KZ KE KI KP KR KW KG LA LV LB LS
LR LY LI LT LU MO MK MG MW MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS
MA MZ MM NA NR NP NL NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH
PN PL PT PR QA RE RO RU RW BL SH KN LC MF PM VC WS SM ST SA SN RS SC SL SG
SX SK SI SB SO ZA GS SS ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TL TG TK TO
TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VE VN VG VI WF EH YE ZM ZW
).freeze
end
User::COUNTRIES.include? "US" #=> true
freeze
阻止修改:
User::COUNTRIES.delete "US" #=> RuntimeError: can't modify frozen Array
<强>更新强>
这里的问题是您的国家/地区数组必须以某种方式保留。你提到has_many
所以Rails似乎参与其中。您可以使用ActiveRecord
的{{3}}方法:
class User < ActiveRecord::Base
serialize :countries
end
这会将countries
属性作为对象保存到数据库并按原样检索:
u = User.new
u.countries = ["US", "CA"]
u.save
u = User.last
u.countries
#=> ["US", "CA"]
它在内部转换为YAML,因此users
表看起来像:
mysql> SELECT * FROM users;
+----+-------------------+---------------------+---------------------+
| id | countries | created_at | updated_at |
+----+-------------------+---------------------+---------------------+
| 1 | ---\n- US\n- CA\n | 2013-09-24 18:24:03 | 2013-09-24 18:24:03 |
+----+-------------------+---------------------+---------------------+
1 row in set (0,00 sec)