Ruby on rails 3 自我参照有很多麻烦
我在使用自参考表时遇到了麻烦 我有一个球体模型,可以容纳行星、恒星和卫星。我想告诉你一件事,另一件事 我看了一下导轨,但我能让它工作 我的模型:Ruby on rails 3 自我参照有很多麻烦,ruby-on-rails-3,has-many,self-join,Ruby On Rails 3,Has Many,Self Join,我在使用自参考表时遇到了麻烦 我有一个球体模型,可以容纳行星、恒星和卫星。我想告诉你一件事,另一件事 我看了一下导轨,但我能让它工作 我的模型: class Orb < ActiveRecord::Base belongs_to :orb_type has_and_belongs_to_many :books belongs_to :orbit, :class_name => "Orb" has_many :orbs, :class_name => "Orb"
class Orb < ActiveRecord::Base
belongs_to :orb_type
has_and_belongs_to_many :books
belongs_to :orbit, :class_name => "Orb"
has_many :orbs, :class_name => "Orb", :foreign_key => "orb_id"
attr_accessible :descr, :nome, :orb_type_id, :book_ids, :orb_id
validates :nome, uniqueness: true, presence: true
end
我想我用的是坏关系的名字,可能是用错了
1.9.3-p448 :002 > earth = Orb.find(1)
Orb Load (0.2ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."id" = ? LIMIT 1 [["id", 1]]
=> #<Orb id: 1, nome: "Terra", descr: "123123", orb_type_id: 1, created_at: "2013-09-25 14:53:35", updated_at: "2013-09-25 14:57:40", orb_id: nil>
1.9.3-p448 :003 > moon = Orb.find(2)
Orb Load (0.2ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."id" = ? LIMIT 1 [["id", 2]]
=> #<Orb id: 2, nome: "Lua", descr: "asd", orb_type_id: 2, created_at: "2013-09-25 14:53:46", updated_at: "2013-09-25 14:55:31", orb_id: nil>
1.9.3-p448 :004 > sun = Orb.find(3)
Orb Load (0.2ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."id" = ? LIMIT 1 [["id", 3]]
=> #<Orb id: 3, nome: "Sol", descr: "asd", orb_type_id: 3, created_at: "2013-09-25 14:53:55", updated_at: "2013-09-25 14:53:55", orb_id: nil>
1.9.3-p448 :006 > moon.orbit=earth
=> #<Orb id: 1, nome: "Terra", descr: "123123", orb_type_id: 1, created_at: "2013-09-25 14:53:35", updated_at: "2013-09-25 14:57:40", orb_id: nil>
1.9.3-p448 :007 > earth.orbit=sun
=> #<Orb id: 3, nome: "Sol", descr: "asd", orb_type_id: 3, created_at: "2013-09-25 14:53:55", updated_at: "2013-09-25 14:53:55", orb_id: nil>
1.9.3-p448 :008 > earth
=> #<Orb id: 1, nome: "Terra", descr: "123123", orb_type_id: 1, created_at: "2013-09-25 14:53:35", updated_at: "2013-09-25 14:57:40", orb_id: nil>
1.9.3-p448 :009 > sun
=> #<Orb id: 3, nome: "Sol", descr: "asd", orb_type_id: 3, created_at: "2013-09-25 14:53:55", updated_at: "2013-09-25 14:53:55", orb_id: nil>
1.9.3-p448 :010 > moon
=> #<Orb id: 2, nome: "Lua", descr: "asd", orb_type_id: 2, created_at: "2013-09-25 14:53:46", updated_at: "2013-09-25 14:55:31", orb_id: nil>
最终没有任何关联,FK仍然为零
Collen orb_id随后添加到模型中。我设置了迁移并将其添加到模型中。我不认为这和我的问题有关
编辑:
现在一切都很奇怪。我将模型更改为:
class Orb < ActiveRecord::Base
belongs_to :orb_type
has_and_belongs_to_many :books
belongs_to :orbit, :class_name => "Orb"
has_many :orbits, :class_name => "Orb", :foreign_key => "orb_id"
attr_accessible :descr, :nome, :orb_type_id, :book_ids, :orb_id
validates :nome, uniqueness: true, presence: true
end
在rails控制台rails c中,我尝试:
1.9.3-p448 :008 > earth = Orb.find(1)
Orb Load (0.2ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."id" = ? LIMIT 1 [["id", 1]]
=> #<Orb id: 1, nome: "Terra", descr: "", orb_type_id: 1, created_at: "2013-09-25 17:51:26", updated_at: "2013-09-25 18:16:58", orb_id: 3>
1.9.3-p448 :009 > earth.orbit
=> nil
1.9.3-p448 :010 > earth.orbits
Orb Load (0.3ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."orb_id" = 1
=> [#<Orb id: 2, nome: "Lua", descr: "", orb_type_id: 2, created_at: "2013-09-25 17:51:40", updated_at: "2013-09-25 18:17:31", orb_id: 1>]
1.9.3-p448 :011 >
怎么回事?轨道可以返回我想要的,但我尝试使用它:
1.9.3-p448 :004 > earth.orbits.nome
NoMethodError: Orb Load (0.4ms) SELECT "orbs".* FROM "orbs" WHERE "orbs"."orb_id" = 1
undefined method `nome' for #<ActiveRecord::Relation:0x00000003d593c0>
from /usr/local/rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.12/lib/active_record/relation/delegation.rb:45:in `method_missing'
from /usr/local/rvm/gems/ruby-1.9.3-p448/gems/activerecord-3.2.12/lib/active_record/associations/collection_proxy.rb:100:in `method_missing'
from (irb):4
from /usr/local/rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
from /usr/local/rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
从技术上讲,如果行星、恒星和卫星都在同一个模型中,那就不太好了。他们的行为都不一样,每个人都应该有自己的模式。根据定义,恒星永远不会绕行星运行,行星也永远不会绕月球运行。通过以现有的方式构建数据库,您正在为损坏的数据进行设置,如果您允许的话,这种情况总会发生 如果你必须把它们都放在天体模型中,我推荐两个模型:一个用于天体恒星、行星、卫星,另一个用于轨道。Orbit类本质上是这样一个表:
Orbit model:
| id | orbited_id | orbiter_id |
--------------------------------
| 0 | planet_id | moon_id |
| 1 | star_id | planet_id |
| 2 | planet_id | moon_id |
| ...| etc | etc |
然后您可以在orb.rb中设置关联:
has_and_belongs_to_many :orbits,
class_name: 'Orb',
join_table: :orbits,
foreign_key: :orbited_id,
association_foreign_key: :orbiter_id,
uniq: true
这将允许您执行以下操作:
>> sun = Orb.find(1)
>> sun.orbits
=> [ <Orb mercury>, <Orb venus>, ..., <Orb pluto> ]
我知道了。我应该使表中的rom使用关系orbit\u id的名称,而不是表名orb\u id 修复一切开始正常工作的问题:
has_many :orbters, class_name: "Orb", foreign_key: "orbit_id"
belongs_to :orbit, class_name: "Orb"
我知道我可以为每种类型建立一个表格,但我有orb_类型的关联,因为我需要的不仅仅是小行星提交的3种类型等等。。。我想在这里放一个自我参照的原因是因为这个表已经可以容纳我想要的所有数据,我不介意这个关系的意思是否是奇怪的,比如说,一颗绕月球运行的恒星,明白了吗。您仍然应该使用我的上述建议,并删除OrbType模型。相反,您可以在orb模型上以列的形式跟踪orb_类型,然后通过执行orb.whereorb_类型:“asteroid”等操作获取所有小行星,但在插入新的orb时,我必须硬编码所有类型;pAnyway,orb_type->orb关系运行良好,与我试图解决的问题无关。我的问题是orb->orb relationOK,仍然不是我会选择orb_类型的路线,因为它对于零增益来说更为复杂。但每个人都有自己的。我上面的解决方案在不改变orb_类型关系的情况下可以很好地工作,所以我将删除那个旁注。我在上面展示的HABTM关系是您想要的自参考关系。