Рельсы "has_one" отношение. Присвоить проект заказчику (метка времени)
Я строю трекер времени. Вы можете создать временную метку с указанием времени начала, времени окончания, клиента и проекта от этого клиента. Таким образом, вы можете увидеть, сколько времени вы потратили на проект или клиента.
Отношения между таблицами с has_many работают отлично, но у меня проблема с отношением has_one.
Мои таблицы:
timestamps customers projects
---------- ------------ -----------
id:integer id:integer id:integer
desc:string customer_name:string project_name:string
customer_id:interger project_id:integer
Мои модели:
timestamp.rb
class Timestamp < ActiveRecord::Base
has_one :customer
has_one :project, through: :customer
end
customer.rb
class Customer < ActiveRecord::Base
belongs_to :timestamp
has_many :projects, dependent: :destroy
end
project.rb
class Project < ActiveRecord::Base
belongs_to :customer
end
Мои цели:
- Создайте одну временную метку со связанным клиентом и проектом:
Timestamp.create({desc: "Something", customer_id: "1", project_id: "6"})
- Получить проект из отметки времени:
Timestamp.find(1).customer.project
Моя проблема:
Я могу сделать это, если я добавлю timestamp_id в таблицу проектов, но с помощью этого метода Rails дублирует каждый проект с определенным timestamp_id при создании новой отметки времени. Но я хочу назначить один project_id метке времени.
К вашему сведению: я использую рельсы 4.2.6 с базой данных MYSQL.
2 ответа
Поскольку вы не хотите иметь дубликаты проектов и дублирующих клиентов на временную метку, вам нужно будет установить только внешние ключи для временной метки. При этом вы хотели бы иметь таблицы со следующими столбцами:
Timestamps
customer_id:integer:index
project_id:integer:index
Customers
Projects
customer_id:integer:index
Вам нужно будет написать и запустить миграцию, чтобы удалить столбцы и добавить столбцы, чтобы это выглядело выше.
Затем измените ассоциации:
class Timestamp < ActiveRecord::Base
belongs_to :customer # change to belongs_to
has_many :projects, through: :customer # you might not need this anymore because of the line below
belongs_to :project # add this line
end
class Customer < ActiveRecord::Base
has_one :timestamp # change to has_one
has_many :projects, dependent: :destroy
end
class Project < ActiveRecord::Base
belongs_to :customer
has_one :timestamp # add this line
end
Тогда вы можете теперь использовать следующее
Timestamp.find(1).customer
Timestamp.find(1).project
Timestamp.find(1).projects # these projects are customer.projects and are not directly associated to the line above, so I don't think you would need to call this
Хорошо, спасибо всем! @Jay-Ar Polisario, ваш ответ не сработал идеально, но заставил меня задуматься о моих отношениях "has_one / has_many", и из-за этого он сработал после нескольких часов переосмысления этих отношений. Спасибо.
Для всех, кто пришел сюда из Google, чтобы найти ответ на похожую проблему:
Начните рисовать ваши таблицы и столбцы на доске или бумаге. Сделайте отношения визуальными! Это помогло мне выяснить правильные отношения.