2016-06-22 4 views
1

Я пытаюсь использовать методы has_one и has_many в одной модели. В задачах задач много задач, но у них также есть одна задача по умолчанию.Использование как has_one, так и has_many ассоциации

Я пытаюсь создать столбец в таблице задач, содержащий идентификатор задачи. Однако, когда я пытаюсь установить эту задачу по умолчанию, она не работает.

class Taskflow < ActiveRecord::Base 
    has_many :tasks 
    has_one :default_task, :class_name => 'Task' 

class Task < ActiveRecord::Base 
    belongs_to :taskflow 

Я засеять базу данных, то в консоли рельсы я пытаюсь назначить задачу быть TaskFlow default_task:

taskflow1 = Taskflow.first 
task1 = Task.first 
taskflow1.default_task = task1 

Это не работает с TaskFlow значением default_task остающегося «ноль». Каков правильный способ достижения желаемого поведения?

Любая помощь будет высоко оценена.

Редактировать

файлов миграции являются:

class CreateTaskflows < ActiveRecord::Migration 
    def change 
    create_table :taskflows do |t| 
     t.string :title 
     t.string :description 
     t.references :default_task 
     t.timestamps null: false 
    end 
    end 
end 

class CreateTasks < ActiveRecord::Migration 
    def change 
    create_table :tasks do |t| 
     t.string :task_type 
     t.text :help 
     t.text :data 
     t.belongs_to :taskflow 
     t.timestamps null: false 
    end 
    end 
end 
+0

первый выключен, он выглядит, как вы никогда не ставили задачу, чтобы «taskflow1.default_task = задача» установит default_task к нулю, потому что задача никогда не устанавливается. У всех задач TaskFlow есть одна и та же задача по умолчанию или она изменяется между экземплярами TaskFlow? –

+0

К сожалению, это была опечатка. Задача по умолчанию может отличаться между экземплярами задач. Большое спасибо. – RobotEyes

ответ

0

Я получил эту работу. Вместо has_one, belongs_to необходим в модели.

class Taskflow < ActiveRecord::Base 
    has_many :tasks 
    belongs_to :default_task, :class_name => 'Task' 

class Task < ActiveRecord::Base 
    belongs_to :taskflow 

Я думаю, что-то связанное с has_one, имеющим обратную связь с моим предположением. http://guides.rubyonrails.org/association_basics.html#the-has-one-association

+1

С помощью belongs_to вы подразумеваете, что задача имеет одно или много TaskFlows, даже если вы не указали явную форму такой ассоциации. Это точно отражает ваши требования? – hypern

1

has_one используется для specifie ассоциацию один-к-одному с другим классом. Этот метод следует использовать только в том случае, если другой класс содержит внешний ключ.

В вашем случае, вы должны использовать belong_to как ссылка default_task в модели TaskFlow (в вашей миграции).

Модель TaskFlow имеет два соотношения:

  • TaskFlow имеет множество задач
  • TaskFlow имеет одну конкретную задачу, задачу по умолчанию.

class Taskflow < ActiveRecord::Base has_many :tasks belongs_to :default_task, :class_name => 'Task'

class Task < ActiveRecord::Base belongs_to :taskflow

, как вы имели его, Rails не будет знать, какие задачи по умолчанию один.

4

Я бы использовал его по-разному. Я бы создал логическое поле default_task в модели Task. И TaskFlow будет иметь следующие HAS_ONE и HAS_MANY ассоциации:

семантически, TaskFlow должны иметь много задач, и имеют одну задачу по умолчанию среди этих задач. И, по моему мнению, задача управления задачами по умолчанию звучит немного искусственно.

Вы также можете добавить функциональность для постоянной поддержки одной задачи в качестве задачи по умолчанию (с битом, установленным в true, более подробно here) или создать задачу по умолчанию во время создания Taskflow. Все зависит от ваших требований.

И, если вы все еще хотите иметь столбец default_task_id быть на вашей модели TaskFlow и использовать HAS_ONE ассоциации, вы можете сделать следующее:

class Taskflow < ActiveRecord::Base 
    has_many :tasks 
    has_one :default_task, class_name: "Task", primary_key: "default_task_id", foreign_key: "id" 
1

Люди здесь правы belongs_to или как взломать HAS_ONE , Я понимаю, что property_to не чувствует себя хорошо в этой ситуации, но если вы используете «ссылку» в таблице, вы обычно всегда хотите использовать belongs_to. Поэтому я хотел бы пометить задачу по умолчанию для самих задач как по умолчанию, но если они могут быть частью разных задач, где разные задачи могут быть по умолчанию, тогда, конечно, это невозможно.

Другой вариант для тех, о которых здесь уже упоминалось: вы можете добавить область действия has_many: tasks. Как это:

has_many :tasks do 
    def default 
    joins(:task_flow).where('tasks.id = task_flows.default_task_id').first 
    end 
end 

Тогда вы можете запросить

@task_flow.tasks.default 
+0

Я не вижу, как он отличается от области видимости (но менее ясен), но, конечно же, Rails очень хорош, потому что вы можете выразить все по-разному, чтобы сделать их понятными и подходящими для конкретной ситуации. Кстати, о has_one «взломать», это не взломать. Параметр 'condition' в' has_one' и 'has_many' является хорошо определенным и полезным для настройки ассоциаций. –

+0

Я называю это «взломать», потому что это противоречит соглашениям. Я думаю, вы можете согласиться, по крайней мере, что вы многое настроили, чтобы has_one работал в модели данных здесь. Edit - PS: Я просто посмотрел на ваш текущий ответ. И отметить его с помощью булевых не похоже на хак. Но перенастроить primary_key и foreign_key для выполнения работы почти напротив конвенции, мне кажется, что это «хак» для меня ^^ – bpieck

+0

Ну, я называю «взломанные» вещи, которые выполняются с целью только сделать что-то работать, даже если оно на самом деле не отражает желаемый дизайн. Давайте рассмотрим наш случай в качестве примера. RobotEyes используется для__по__по_о__по_определению_ в Taskflow и в то же время Taskflow has_many задач. Это даже звучит искусственно: поток задач имеет много задач и относится к задаче по умолчанию. Гораздо лучшей версией будет: задача имеет много задач, и одна из них является задачей по умолчанию (я все еще считаю, что bool в задаче будет лучшим решением, поскольку это позволит вам иметь более 1 задачу по умолчанию позже). –

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