簡體   English   中英

同時使用has_one和has_many關聯

[英]Using both has_one and has_many association

我正在嘗試在一個模型中使用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

我在數據庫中播種然后在rails控制台中嘗試將任務分配為任務流default_task:

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

這不適用於任務流default_task值剩余'nil'。 實現理想行為的正確方法是什么?

任何幫助將非常感激。

編輯

遷移文件是:

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

我會以不同的方式實現它。 我將在Task模型上創建一個布爾字段default_task。 而Taskflow將具有以下has_one和has_many關聯:

class Taskflow < ActiveRecord::Base
    has_many :tasks
    has_one :default_task, class_name: 'Task', condition: proc{"tasks.default_task = true"}

從語義上講,Taskflow應該有許多任務,並且在這些任務中有一個默認任務。 而且我認為任務流屬於默認任務聽起來有點人為。

您還可以添加一項功能,以持續維護單個任務作為默認任務(位設置為true, 此處提供更多詳細信息),或者在創建任務流時創建默認任務。 這一切都取決於您的要求。

並且,如果您仍希望將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"

has_one 用於指定與另一個類的一對一關聯。 僅當其他類包含外鍵時才應使用此方法。

在您的情況下,您應該使用belongs_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不知道哪個任務是默認任務。

這里的人對於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

然后你可以要求

@task_flow.tasks.default

我得到了這個工作。 模型中需要belongs_to而不是has_one

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM