0

自己参照テーブルに問題があります。

惑星、星、月を保持できるオーブ モデルを入手しました。あるものが別のものを「周回」していることを伝えたい

Railsガイドを見ましたが、うまくいきました

私のモデル:

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 はまだゼロです。

collun 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

レールコンソール(レール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>'
4

2 に答える 2

0

技術的には、惑星、星、月がすべて同じモデル内にあるのは良くありません。それらはすべて異なる動作をするため、それぞれ独自のモデルを保証する必要があります。たとえば、恒星が惑星を周回することはなく、惑星が月を周回することもありません (定義による)。データベースをこのように構造化することで、破損したデータに備えることができます。これは、許可した場合に常に発生します。

モデル内にすべてを含める必要がある場合はOrb、2 つのモデルをお勧めします。1 つはOrbs(星、惑星、月) 用で、もう 1 つはOrbits. クラスは基本的に次の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> ]
于 2013-09-25T16:41:59.220 に答える