Ruby attr_accessor并收集括号

时间:2013-02-01 01:11:12

标签: ruby-on-rails ruby attr-accessor

我以为我理解了attr_ *和map(&:name.to_proc).join('')的简写符号,但今天我遇到了这个问题。

为什么设置attr_accessor会使我无法编写类似NaughtyWord.all.collect(&:word)的内容,而是要求我写出更长的NaughtyWord.all.collect{|naughty_word| naughty_word["word"]}

class NaughtyWord < ActiveRecord::Base
  attr_accessor :word, :must_review

  validates_presence_of :word

  def self.regex_filter
    words = NaughtyWord.all.collect(&:word).join("|")
  end
end

#irb(main):014:0> NaughtyWord.all.collect(&:word)
#  NaughtyWord Load (0.4ms)  SELECT `naughty_words`.* FROM `naughty_words` 
#=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]

#irb(main):024:0> NaughtyWord.last
#  NaughtyWord Load (0.3ms)  SELECT `naughty_words`.* FROM `naughty_words` ORDER BY `naughty_words`.`id` DESC LIMIT 1
#=> #<NaughtyWord id: 11, word: "word", must_review: true>

#irb(main):025:0> NaughtyWord.last.word
#  NaughtyWord Load (0.6ms)  SELECT `naughty_words`.* FROM `naughty_words` ORDER BY `naughty_words`.`id` DESC LIMIT 1
#=> nil

# irb(main):026:0> NaughtyWord.last["word"]
# NaughtyWord Load (0.6ms)  SELECT `naughty_words`.* FROM `naughty_words` ORDER BY `naughty_words`.`id` DESC LIMIT 1
# => "word"

#irb(main):030:0> NaughtyWord.all.collect{|naughty_word| naughty_word["word"]}
# NaughtyWord Load (0.6ms)  SELECT `naughty_words`.* FROM `naughty_words` 
#=> ["word", "word", "word", "word", "word", "word", "word", "word", "word", "word", "word"]

如果我注释掉attr_accessor行

,那么一切正常

1 个答案:

答案 0 :(得分:1)

我认为您要使用attr_accessible代替attr_accessor。第一个是用于质量分配属性的白色标签的Rails方法,因此可以在控制器中使用User.new params[:user]之类的东西。第二个是纯Ruby,它是为给定实例变量创建读写(也称为getter和setter)方法的助手。

所以你在使用attr_accessor做的事实上是覆盖了ActiveRecord所做的属性访问器方法,这就是它返回nil的原因。