将公共属性注入activerecord类的正确方法是什么?

时间:2010-08-16 00:03:58

标签: ruby-on-rails activerecord mixins

我计划使用此模块(此处为完整示例http://pastie.org/1098444

puts "Name_and_key was referenced."

module Name_and_key

  def normalize(s)
    s.mb_chars.normalize(:kd).gsub(/[^\-x00-\x7F]/n, '').to_s
  end

  def name=(name)
    self[:name] = name
    self[:key] = normalize(name).downcase
  end

  def name
    self[:name]
  end

  def key=(key)
    self[:key] = normalize(key).downcase
  end

  def key
    self[:key]
  end

end

但似乎这些值没有到达模型。

 class Category < ActiveRecord::Base
  include Name_and_key

  has_many :tiles
  validates_presence_of :name, :key
end

cat = Category.create do |c|
 c.name = "cat"
end
  

ActiveRecord :: StatementInvalid:SQLite3 :: ConstraintException:categories.name可能不为NULL:INSERT INTO“categories”(“created_at”,“updated_at”,“id”)VALUES('2010-08-15 23:20 :43','2010-08-15 23:20:43',980190962)

这是否是一种有效的方法,如果不是这样做怎么办?如果确实,我的错误是什么?

单元测试失败

test "can be created" do
cat = Category.create do |c|
  c.name = "cat"
end
tile = Tile.create do |t|
  t.name = "test"
  t.category = cat
end
assert tile.save

一些痕迹

  1) Error:

test_can_be_created(TileTest): ActiveRecord :: StatementInvalid:SQLite3 :: ConstraintException:categories.name可能不为NULL:INSERT INTO“categories”(“created_at”,“updated_at”,“id”)VALUES('2010-08-16 02:06:43' ,'2010-08-16 02:06:43',980190962)     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract_adapter.rb:202:in rescue in log' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract_adapter.rb:194:in log'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/sqlite_adapter.rb:135:in execute' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract/database_statements.rb:239:in insert_fixture'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:634:in block in insert_fixtures' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:570:in each'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:570:in insert_fixtures' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:514:in块(4个级别) )在create_fixtures'中     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:514:in each' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:514:in块(3个级别) )在create_fixtures'中     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in transaction' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:512:in在create_fixtures中阻止(2个级别)     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract_adapter.rb:104:in disable_referential_integrity' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:503:in阻止create_fixtures'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activesupport-3.0.0.rc/lib/active_support/benchmarkable.rb:55:in silence' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:502:in create_fixtures'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:961:in load_fixtures' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activerecord-3.0.0.rc/lib/active_record/fixtures.rb:926:in setup_fixtures'     /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:409:in _run_setup_callbacks' /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activesupport-3.0.0.rc/lib/active_support/testing/setup_and_teardown.rb:34:in run'

1 个答案:

答案 0 :(得分:1)

我建议添加validates_presence_of :name来捕获ruby端的错误。您的应用尝试将看似有效的对象保存到数据库,名称为NULL,ruby端允许。现在你的数据库爆炸了,因为你在那里设置了一个NOT NULL,这与你在那里保存的不一样。