2014-09-11 4 views
0

Как смоделировать следующий сценарий? Мне нужно получить доступ к велосипеду из колес во время проверки, поэтому я не могу просто опустить has_one.Обратное направление для нескольких отношений has_one

class Bicycle < ActiveRecord::Base 
    belongs_to :front_wheel, :class_name => 'Wheel' 
    belongs_to :back_wheel, :class_name => 'Wheel' 
end 

class Wheel < ActiveRecord::Base 
    has_one :bicycle 
end 

b = Bicycle.new 
b.front_wheel = Wheel.new 
b.back_wheel = Wheel.new 

b.save 

# Fails with 
ActiveModel::MissingAttributeError: can't write unknown attribute `wheel_id' 

БД схема:

create_table "bicycles", force: true do |t| 
    t.integer "front_wheel_id" 
    t.integer "back_wheel_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

create_table "wheels", force: true do |t| 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

Если кто-то находит лучшее название для этого вопроса, пожалуйста, обновите его или черкните.

+2

Что ваша схема БД? –

+0

Можете ли вы показать схему велосипедов и колес таблиц? – Surya

+0

Просто добавлена ​​схема БД. – Remo

ответ

1

Проблема в том, что ваш has_one будет искать wheel_id на столе. Но у вас будут front_wheel_id и back_wheel_id, и колесо не знает, если это переднее колесо или заднее колесо. Я не знаю, можете ли вы установить два возможных варианта для внешнего ключа. Я бы предположил, что нет. Это означает, что ваша структура нуждается в переосмыслении.

Вы можете использовать однонаправленное наследование, поскольку я предполагаю, что передние и задние колеса будут одинаковыми. Таким образом, у вас будет модель колес, а база данных колес будет иметь столбец типа с моделью спереди и сзади, унаследовавшей его.

class Wheel < ActiveRecord::Base  
end 

class FrontWheel < Wheel 
    has_one :bicycle 
end 

class BackWheel < Wheel 
    has_one :bicycle 
end 

Тогда вы бы

b = Bicycle.new 
b.front_wheel = FrontWheel.new 
b.back_wheel = BackWheel.new 

b.save 

Тогда из-за названий модели переднее колесо должно успешно искать front_wheel_id и заднее колесо будет искать back_wheel_id