【问题标题】:What's the correct way to inject common properties into an activerecord class?将公共属性注入活动记录类的正确方法是什么?
【发布时间】:2010-08-16 00:03:57
【问题描述】:

我打算使用这个模块(这里有完整的例子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:inlog' /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:ininsert_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:ineach' /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:inblock(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:inblock(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:inblock ( 2 级)在 create_fixtures' /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:inblock 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:increate_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:insetup_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:inrun'

【问题讨论】:

    标签: ruby-on-rails activerecord mixins


    【解决方案1】:

    我建议添加 validates_presence_of :name 以捕获 ruby​​ 端的这些错误。您的应用程序尝试将看似有效的对象保存到数据库,名称为 NULL,这是 ruby​​ 方面允许的。现在你的数据库爆炸了,因为你在那里设置了一个 NOT NULL,它不喜欢你在那里保存的内容。

    【讨论】:

    • 不应该达到同样的效果吗?
    • 它真的没有改变任何东西。我不断收到同样的错误。
    • 对不起。 #read_attribute 不是您想要的。似乎 #[]= 也有效。我认为你的问题是你过早地保存了对象并且在你的数据库上得到了一些 NOT NULL 列。我建议添加 validates_presence_of :name 以捕获 ruby​​ 端的这些错误。
    • 类别验证了这一点。当然问题是空值。我的问题是 - 鉴于上述情况:为什么它们为空?
    • 啊哈! ruby-1.9.2-rc2 > c = Category.new(:name =>"Test") Name_and_key 被引用。 NoMethodError:私有方法write_attribute' called for #&lt;Category:0x000001029f3e60&gt; from /Users/janlimpens/.rvm/gems/ruby-1.9.2-rc2@rails3/gems/activemodel-3.0.0.rc/lib/active_model/attribute_methods.rb:364:in method_missing'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2011-06-22
    • 2014-04-13
    • 2010-11-11
    • 2011-06-27
    • 1970-01-01
    相关资源
    最近更新 更多