#ruby-on-rails #ruby #activerecord #relationships #scaffold
#ruby-on-rails #ruby #activerecord #отношения #каркас
Вопрос:
Я разработчик Java, последние несколько дней изучал Rails. У меня есть приложение Java EE (использует режим гибернации для ORM), которое я пытаюсь перенести на Rails. Я использовал строительные леса для создания нескольких моих моделей. Но у меня есть другие модели, которые содержат ссылки на другие модели. Как мне определить отношения? Могу ли я также использовать это?
Вот пример того, что я пытаюсь сделать.
public class Engine {
private int valves;
private int capacity;
private int rpm;
}
Я могу создать класс Engine в ruby, просто выполнив следующее:
rails generate scaffold Engine valves:integer capacity:integer rpm:integer
Вот сложная часть для меня:
public class Car {
private Engine engine;
}
Как мне создать класс Car в Ruby?
Ответ №1:
Если я правильно понимаю, вы ищете ассоциации. Вот отличное руководство, которое вы должны прочитать. Здесь нужно понимать, что вы определяете в своих моделях, как они связаны друг с другом, с помощью ряда методов, описанных в этом руководстве.
Вот что я бы посоветовал вам сделать:
rails generate scaffold Car <db columns>
rails generate model Engine valves:integer capacity:integer rpm:integer car_id:integer
В ваших двух моделях:
class Car < ActiveRecord::Base
has_one :engine
end
class Engine < ActiveRecord::Base
belongs_to :car
end
На самом деле вы можете сгенерировать каркас для обеих моделей…это создаст контроллер и представления. Но в этом случае может иметь смысл добавить
accepts_nested_attribues_for :engine
вместо этого на вашу модель автомобиля. Это позволит вам управлять манипуляциями с моделью двигателя из контроллера и представлений модели автомобиля.
В любом случае, я надеюсь, что это поможет вам начать находить то, что вам нужно.
Ответ №2:
Вы можете сделать это с помощью references
помощника activerecord migration.
rails generate scaffold Car engine:references ...
это добавит :
t.references :engine
в вашем файле миграции
has_many :engines
в вашем файле модели автомобиля
belongs_to :car
в вашем файле модели движка
Не забудьте проверить rails api на наличие опций (по умолчанию, обратные вызовы отношений …) (здесь для примера: http://railsapi.com/doc/rails-v3.0.8rc1 /)
Ответ №3:
Вы должны узнать больше о Ruby. Ruby не является статическим языком, что означает, что каждая переменная может содержать объекты любого типа.
Команда rails generate использует valves:integer и т. Д. Только Для целей базы данных, Поскольку базы данных нуждаются в этой информации.
Что касается вашей проблемы с отношениями, вам следует прочитать о has_many, bleongs_to и т. Д. (см http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html ) В Rails вы бы определили свое отношение следующим образом
class Car
belongs_to :engine
end
class Engine
has_many :cars
end
Кроме того, вы должны добавить внешний ключ engine_id в Car.
Это работает, потому что в Rails используется несколько соглашений.
Без базового руководства вы далеко не продвинетесь.
Комментарии:
1. моя единственная мысль об этом ответе заключается в том, что has_many может быть неправильным путем. Мне кажется, что экземпляр двигателя может находиться только в одном автомобиле одновременно … и я не видел никаких метаданных в столбцах таблицы моделей, чтобы это выглядело как тип двигателя. Опять же, я предлагаю взглянуть на руководство по ассоциации
2. Возможно, вы правы. Я предположил, что Engine — это тип, поскольку в классе Engine нет указания на какую-либо информацию о типе.
Ответ №4:
Для отношений нет каркасов, вы должны научиться делать это «вручную» (что не слишком требовательно). Взгляните на «Направляющие рельсы», а здесь «Активная ассоциация записей».
В вашем примере вам нужно выполнить следующие шаги:
- Создайте миграцию для переноса базы данных:
rails g migration AddIds
-
Измените миграцию, чтобы включить дополнительный идентификатор, который у вас должен быть:
... add_column :engines, :car_id, :integer
-
Добавьте в свои модели следующий код:
class Car has_one :engine ... end class Engine belongs_to :car ... end