2016-06-22 21 views
1

私はhas_oneメソッドとhas_manyメソッドを1つのモデルにしようとしています。タスクフローには多くのタスクがありますが、単一のデフォルトタスクもあります。has_oneとhas_manyの両方の関連付けを使用する

タスクのIDを含むタスクフローテーブルに列を作成しようとしています。しかし、私が試して、そのデフォルトのタスクを設定すると動作しません。

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

class Task < ActiveRecord::Base 
    belongs_to :taskflow 

私はタスク・フローdefault_taskするタスクを割り当てようとレールコンソールで、データベースをシード:

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

これは「ゼロ」を、残りのタスク・フロー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

を要求することができます。すべてのTaskFlowsが同じデフォルトタスクを持つか、それとも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を使用すると、明示的にそのような関連付けが指定されていなくても、タスクには1つまたは複数のTaskFlowsがあることを意味しています。それはあなたの要求を正確に反映していますか? – hypern

1

has_oneのは、別のクラスと一対一の関連付けをspecifieするために使用されます。このメソッドは、他のクラスに外部キーが含まれている場合にのみ使用してください。

belongs_to default_taskリファレンスはTaskFlowモデル(移行時)にあるため、この場合は使用する必要があります。

  • Aタスクフローが
  • Aタスク・フローは、デフォルトのタスクである一つの特定のタスクを持っている多くのタスクがあります。

    タスクフロー・モデルは、2人の関係があります。

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を作成します。そして、タスクフローは以下にhas_oneとhas_manyの関連を持っているでしょう:

は意味的に、タスクフローは、多くのタスクを持っており、これらのタスクのうちの1つのデフォルトのタスクを持っている必要があります。そして、私の意見では、タスクフローはデフォルトのタスクに属していますが、少し人工的な音です。

単一のタスクをデフォルトタスク(ビットがtrueに設定されている、詳細はhere)として常に維持する機能を追加したり、タスクフローの作成時にデフォルトタスクを作成することもできます。それはあなたの要求に依存します。

AND、あなたはまだあなたのタスクフローモデルになるとhas_oneの関連付けを使用するようにdefault_task_id列を持っているしたい場合は、次の操作を行うことができます:ここ

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をハックする権利についてですが。私はbelongs_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 

その後、タスクが設定されることはありませんので、「taskflow1.default_task =タスクは」nilにdefault_taskを設定しますので、あなたは、タスクを設定したことがないように見える最初のオフ

@task_flow.tasks.default 
+0

どのようにスコープとは違うのか分かりませんが、Railsは非常に優れています。なぜなら、特定の状況に適したさまざまな方法で表現できるからです。ところで、has_one "ハック"については、ハックではありません。 'has_one'と' has_many'の 'condition'パラメータは、アソシエーションをカスタマイズするための明確かつ有効な動作です。 –

+0

慣習と矛盾するので、私はそれを「ハック」と呼びます。少なくとも、ここではデータモデルでhas_oneを動作させるために多くの設定を済ませていると思います。 編集 - PS:あなたの現在の答えを調べました。ブール値でマークするのはハックのような気がしません。しかし、仕事をするためにprimary_keyとforeign_keyを再設定するためには、大会の反対のことは私に "ハック"のように感じます^^ – bpieck

+0

まあ、私は「ハック」と呼んでいます。本当に希望のデザインを反映していません。現在のケースを例として考えてみましょう。 RobotEyesは、Taskflowのdefault_taskにbelongs_toを使用し、同時にTaskflow has_many tasksを使用しました。人為的に聞こえるかもしれません。タスクフローには多くのタスクがあり、デフォルトのタスクに属しています。タスクフローには多くのタスクがあり、そのうちの1つはデフォルトタスクです(これは、後で1つ以上のデフォルトタスクを持つことができるので、タスクのブールがより良いソリューションになると思います)。 –

関連する問題