同时使用 has_one 和 has_many 关联
Using both has_one and has_many association
我正在尝试在一个模型中使用 has_one 和 has_many 方法。一个任务流可以有很多任务,但它也有一个默认任务。
我正在尝试在任务流 table 中创建一个包含任务 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
我成功了。模型中需要 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
has_one用于指定与另一个class的一对一关联。仅当另一个 class 包含外键时才应使用此方法。
在您的情况下,您应该使用 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 不知道哪个任务是默认任务。
我会以不同的方式实施它。我会在任务模型上创建一个布尔字段 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 列在您的任务流模型中并使用 has_one 关联,您可以执行以下操作:
class Taskflow < ActiveRecord::Base
has_many :tasks
has_one :default_task, class_name: "Task", primary_key: "default_task_id", foreign_key: "id"
这里的人关于 belongs_to 或如何破解 has_one 是正确的。我知道 belongs_to 在这种情况下感觉不对,但是如果您在 table 中使用 "referencing",您通常总是想使用 belongs_to。所以我假设将任务本身的默认任务标记为默认 - 但如果它们可以是不同 task_flows 的一部分,其中不同的任务可能是默认 - 那么当然这是不可能的。
这里已经提到的另一个选项是:您可以向 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
我正在尝试在一个模型中使用 has_one 和 has_many 方法。一个任务流可以有很多任务,但它也有一个默认任务。
我正在尝试在任务流 table 中创建一个包含任务 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
我成功了。模型中需要 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
has_one用于指定与另一个class的一对一关联。仅当另一个 class 包含外键时才应使用此方法。
在您的情况下,您应该使用 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 不知道哪个任务是默认任务。
我会以不同的方式实施它。我会在任务模型上创建一个布尔字段 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 列在您的任务流模型中并使用 has_one 关联,您可以执行以下操作:
class Taskflow < ActiveRecord::Base
has_many :tasks
has_one :default_task, class_name: "Task", primary_key: "default_task_id", foreign_key: "id"
这里的人关于 belongs_to 或如何破解 has_one 是正确的。我知道 belongs_to 在这种情况下感觉不对,但是如果您在 table 中使用 "referencing",您通常总是想使用 belongs_to。所以我假设将任务本身的默认任务标记为默认 - 但如果它们可以是不同 task_flows 的一部分,其中不同的任务可能是默认 - 那么当然这是不可能的。
这里已经提到的另一个选项是:您可以向 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