是否可以删除"默认"什么是ActiveRecord关系的规则?

时间:2018-06-08 09:23:58

标签: ruby-on-rails-5 rails-activerecord

简短版本:

有没有办法去" unscope" Rails 5.0中的ActiveRecord belongs_to(或其他)关联?

更长版本:

我正在开发一个Rails项目,其中每个" Job"被分配到"部门"用于组织目的。在大多数情况下,可以根据作业详细信息自动推断部门,但有一些情况下必须手动将作业分配给其他部门。

为了解决这个问题,我在Job表中添加了一个department_id列,目的是让事情按如下方式运行:

  • 如果department_id不为NULL,请按照惯例将作业加入部门。
  • 否则,请回到"推断"工作/部门加入逻辑。

根据Rails documentation,这是可能的:

  

有时您可能希望自定义所使用的查询   属于。这种定制可以通过示波器块实现。对于   例如:

class Book < ApplicationRecord
  belongs_to :author, -> { where active: true },
                        dependent: :destroy
end
     

您可以使用范围内的任何标准查询方法   块。

因此,我尝试按如下方式定义关系(为了演示目的而简化):

belongs_to :department, -> { unscoped.where(id: 7) }

...我的想法是.unscoped会删除默认的where departments.id = [jobs.department_id]逻辑,允许我改为定义自定义规则。

然而,这并没有实际取消范围;生成的SQL是:

SELECT  `departments`.*
FROM `departments`
WHERE `departments`.`id` = 11 AND `departments`.`id` = 7
LIMIT 1

我的猜测是在执行自定义查询块之后应用默认的WHERE逻辑,这意味着.unscoped没有任何效果。

其他一些事情:

  • 我知道我可以简单地将department_id设置为&#34;预期&#34;创建新作业时的值。但是,这会有一些缺点:
    • 我需要追溯设置数据库中每个现有作业的department_id(可能需要相当长的时间)。
    • 如果特定类型的工作被重新分配到不同的&#34;默认&#34;部门,任何现有的工作仍将分配给以前的&#34;部。
    • 同样,如果要更新作业的详细信息,使其属于不同部门的职权范围,则用户需要手动重新分配。
  • 我知道我可以在Job模型上定义一个方法 - 或一个自定义范围 - 而不是在这里使用belongs_to,但是出于这个问题的目的,让我说我绝对要做这是通过ActiveRecord关系实现的。

2 个答案:

答案 0 :(得分:0)

我认为你有点倒退了。如果你有一个department_id,让rails成为rails,部门方法应该返回它。然后还有

def assumed_department
  return department || guessed_department
end

def guessed_department
  <your logic for guessing>
end

如果你有一堆已经使用'部门'的代码,就像我正在使用assume_department那么你会想要删除department_id并添加assigned_department_id

belongs_to assigned_department, class: 'Department' # check the belongs_to docs

然后您的department方法返回assigned_department || guessed_department     等...

但主要是如果你有关系,那么你应该让你的数据库成为一个数据库,并添加关系并始终分配它。

答案 1 :(得分:0)

你很难对抗框架和数据库。

  

我需要追溯设置每个现有作业的department_id   在数据库中(可能需要相当长的时间)。

烨。做吧。

  

如果特定类型的工作被重新分配到不同的&#34;默认&#34;   部门,任何现有的工作仍将分配给以前的&#34;   部。

然后也许你想要一个拥有并且属于许多表之间 - job_category或者其他一些。然后你可以改变它指向的工作,并且所有引用它的工作都会被更新。

  

同样,如果要更新作业的详细信息   属于不同部门的职权范围,用户需要   手动重新分配它。

是的 - 所以添加一个前/后回调,看到标准已更新,然后分配相应的作业/类别。