Как я могу создавать ссылки на объекты в Ruby в ActiveRecords?

#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:

Для отношений нет каркасов, вы должны научиться делать это «вручную» (что не слишком требовательно). Взгляните на «Направляющие рельсы», а здесь «Активная ассоциация записей».

В вашем примере вам нужно выполнить следующие шаги:

  1. Создайте миграцию для переноса базы данных: rails g migration AddIds
  2. Измените миграцию, чтобы включить дополнительный идентификатор, который у вас должен быть:

     ...
    add_column :engines, :car_id, :integer
      
  3. Добавьте в свои модели следующий код:

     class Car
      has_one :engine
      ...
    end
    class Engine
      belongs_to :car
      ...
    end