0

У меня есть модель комнаты. В каждом номере есть 6 выходов (север, восток, юг, запад, вверх, вниз), и я должен быть в состоянии сделать что-то вроде Room.first.nr, чтобы получить номер к северу от первого. Модель I изготовлен заключается в следующем:RoR: Модель, ссылающаяся на себя несколько раз

class Room < ApplicationRecord 

    has_one :nr, class_name: 'Room', foreign_key: :id 
    belongs_to :sr, class_name: 'Room' 

    has_one :er, class_name: 'Room', foreign_key: :id 
    belongs_to :wr, class_name: 'Room' 

    has_one :sr, class_name: 'Room', foreign_key: :id 
    belongs_to :nr, class_name: 'Room' 

    has_one :wr, class_name: 'Room', foreign_key: :id 
    belongs_to :er, class_name: 'Room' 

    has_one :ur, class_name: 'Room', foreign_key: :id 
    belongs_to :dr, class_name: 'Room' 

    has_one :dr, class_name: 'Room', foreign_key: :id 
    belongs_to :ur, class_name: 'Room' 

end 

Однако при этом в рельсах с

Room.create!(title:'sometitle', description:'somedescription', er: Room.first) 

Я получаю это:

ActiveRecord::RecordInvalid: Validation failed: Sr must exist, Wr must exist, Nr must exist, Dr must exist, Ur must exist 

Я играл с inverse_of тоже безрезультатно.

Вот моя миграция:

class CreateRooms < ActiveRecord::Migration[5.0] 
    def change 
    create_table :rooms do |t| 
     t.string :title, null: false 
     t.text :description, null: false 

     t.integer :nr_id, null: true 
     t.integer :er_id, null: true 
     t.integer :sr_id, null: true 
     t.integer :wr_id, null: true 
     t.integer :ur_id, null: true 
     t.integer :dr_id, null: true 

     t.timestamps 
    end 

    add_index :rooms, :nr_id 
    add_index :rooms, :er_id 
    add_index :rooms, :sr_id 
    add_index :rooms, :wr_id 
    add_index :rooms, :ur_id 
    add_index :rooms, :dr_id 

    end 
end 

ответ

0

Хорошо, потребовалось некоторое время, но я понял.

Модель принимает такую ​​форму:

class Room < ApplicationRecord 

    has_one :nr, class_name: 'Room', foreign_key: 'sr_id', inverse_of: :sr 

    has_one :er, class_name: 'Room', foreign_key: 'wr_id', inverse_of: :wr 

    has_one :sr, class_name: 'Room', foreign_key: 'nr_id', inverse_of: :nr 

    has_one :wr, class_name: 'Room', foreign_key: 'er_id', inverse_of: :er 

    has_one :ur, class_name: 'Room', foreign_key: 'dr_id', inverse_of: :dr 

    has_one :dr, class_name: 'Room', foreign_key: 'ur_id', inverse_of: :ur 

end 

Так что я могу сделать

a=Room.create(title:'the title', description: 'the description') 
a.er = Room.find(1) 
a.save 

и это справедливо:

Room.find(1).wr == Room.last 

все равно спасибо @ Jay-Ar Polidario

1

Вы конфликтующие имена ассоциаций (т.е. has_one :nr и belongs_to :nr). Должно быть что-то вроде следующего:

class Room < ApplicationRecord 

    belongs_to :sr, class_name: 'Room' 
    belongs_to :wr, class_name: 'Room' 
    belongs_to :nr, class_name: 'Room' 
    belongs_to :er, class_name: 'Room' 
    belongs_to :dr, class_name: 'Room' 
    belongs_to :ur, class_name: 'Room' 

end 

Я не думаю, что вы все еще нужны has_one отношения. Потому что вы уже можете получить номера во всех направлениях только с этими belongs_to

+0

спасибо за Ваш ответ. К сожалению, я все еще получаю 'ActiveRecord :: RecordInvalid: не удалось выполнить проверку: Sr должен существовать, Wr должен существовать, Nr должен существовать, Dr должен существовать, Ur должен существовать. –

+0

Есть ли у вас уникальные проверки в вашей модели' Room'? Если нет, есть ли у вас уникальные проверки в вашей унаследованной модели 'ApplicationRecord'? Эти ошибки проверки, которые вы получаете, - это потому, что у вас есть уникальные проверки этих атрибутов, где-то в вашем коде. –

+0

нет, это странно. Однако вы указали мне в правильном направлении. См. Мой ответ. –