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

发布于 2024-09-14 07:18:48 字数 4584 浏览 9 评论 0原文

我计划使用这个模块(完整的例子在这里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 救援日志' /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 执行' /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: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块(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:increate_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:in运行'

I planned on using this module (full exmpample here 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

but it seems these values do not arrive at the model.

 class Category < ActiveRecord::Base
  include Name_and_key

  has_many :tiles
  validates_presence_of :name, :key
end

and

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

ActiveRecord::StatementInvalid: SQLite3::ConstraintException: categories.name may not be NULL: INSERT INTO "categories" ("created_at", "updated_at", "id") VALUES ('2010-08-15 23:20:43', '2010-08-15 23:20:43', 980190962)

Is this a valid approach at all, if not how could this be done? If indeed, what is my mistake?

A failing unit test

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

end

Some trace

  1) Error:

test_can_be_created(TileTest):
ActiveRecord::StatementInvalid: SQLite3::ConstraintException: categories.name may not be 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
block (4 levels) in 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
block (3 levels) in 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
block (2 levels) in 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:in
block 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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

狂之美人 2024-09-21 07:18:48

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

I suggest adding validates_presence_of :name to capture those errors on the ruby side. Your app tries to save a seemingly valid object to the DB, with name being NULL, which the ruby side allows. Now your DB blows up because you set a NOT NULL there, which doesn't like what you're saving there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文