2015-06-09 3 views
1

В моем приложении у меня две модели: Task и Guideline. Каждый Task может иметь много Guidelines, и каждый Guideline может принадлежать многим Tasks. Как бы установить связь между этими двумя моделями, если это возможно даже с ActiveRecord? Я думал о структурировании его следующим образом:Rails 4 - Как структурировать отношения модели?

class Task < ActiveRecord::Base 
    has_many :guidelines 
end 

class Guideline < ActiveRecord::Base 
    belongs_to :task 
end 

Однако, я понимаю, что belongs_to будет ассоциировать Guideline только один Task, установив его task_id поле. Это означает, что если заданный Guideline назначен другому Task, первая ассоциация будет потеряна. Пожалуйста, поправьте меня, если я ошибаюсь.

Я изучил отношения has_and_belongs_to_many, но Guidelines не может быть Tasks; они могут принадлежать только многим задачам. В настоящее время у меня есть система, в которой я храню в массиве идентификаторы всех выбранных Guidelines для данного Task, но я предпочел бы использовать встроенные ассоциации, если это возможно.

Любая помощь была бы принята с благодарностью.

+0

От многих до многих отношений? =) http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association – Gerep

ответ

1

Это по-прежнему принципиально has_and_belongs_to_many отношения с присоединиться к таблице:

+-------+  +-----------------+  +------------+ 
| Tasks |-----| GuidelinesTasks |-----| Guidelines | 
+-------+  +-----------------+  +------------+ 

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

В Rails вы можете моделировать это несколькими способами в зависимости от того, имеет ли таблица guidelines_tasks значения, которые вы хотите отслеживать. Оба используют ту же структуру данных:

# Migration 
class AddTasksAndGuidelines < ActiveRecord::Migration 
    def change 
    create_table :tasks do |t| 
     … 
    end 

    create_table :guidelines do |t| 
     … 
    end 

    create_join_table :guidelines, :tasks 
    end 
end 

С этим, первая модель является классическим has_and_belongs_to_many:

# habtm 
class Tasks < ActiveRecord::Base 
    has_and_belongs_to_many :guidelines 
end 

class Guidelines < ActiveRecord::Base 
    has_and_belongs_to_many :tasks 
end 

Вторая модель-полезной, если GuidelinesTask имеет атрибуты своей собственной рефлексивно has_many through::

class Tasks < ActiveRecord::Base 
    has_many :guidelines_tasks 
    has_many :guidelines, through: :guidelines_tasks 
end 

class GuidelinesTask < ActiveRecord::Base 
    has_many :tasks 
    has_many :guidelines 
end 

class Guidelines < ActiveRecord::Base 
    has_many :guidelines_tasks 
    has_many :tasks, through: :guidelines_tasks 
end 

Любой из них будет работать.

+0

Благодарим за объяснение, особенно часть интерпретации! Я думаю об этом, и у меня есть отношения «has_and_belongs_to_many», если я не осознаю это. В каких моделях я бы указал эту ассоциацию? И то и другое? – Alexander

+0

Вы бы поставили его на оба. Я расширил этот мой ответ, чтобы предоставить пару различных вариантов для этого. Либо работает, но и требует дополнительной модели, выходящей за таблицу, требуемую независимо. –

+0

Большое спасибо за вашу помощь! – Alexander

0

Вы можете использовать ассоциацию has_and_belongs_to_many. Это позволяет вам делать такие вещи: Task.first.guidlinesGuidline.first.tasks, если вам нужно).

0

Вы можете использовать has_and_belongs_to_many ассоциация

Ваш код модели будет

класс Task < ActiveRecord :: Base

has_and_belongs_to_many :guidelines 

конец

класс Руководство < ActiveRecord :: Base

has_and_belongs_to_many :tasks 

конец

Кроме того, необходимо создать таблицу в базе данных по имени guidelines_tasks с последующим переносом кода create_table: guidelines_tasks, ID: ложные делать | т |

t.belongs_to :guideline, index: true 
    t.belongs_to :task, index: true 

end 
Смежные вопросы