验证阵列活动记录中的包含时出错



我在将以下句子翻译到Rails范围时遇到了一些问题:

SELECT COUNT(*) FROM permission_activities pa 
JOIN activities a ON pa.activity_id = a.id 
WHERE a.method = :method AND :url ~ a.url_regex AND pa.permission_id IN(:permission_ids)

我带了一些类似的东西:

class PermissionActivity < ApplicationRecord
belongs_to :permission
belongs_to :activity
scope :allowed_access, lambda { |permissions, url, method|
includes(:activity).where(
'activity.method = :method AND :url LIKE activity.url_regex
AND permission_activity.permission_id IN :permissions',
method: method, url: url, permissions: permissions
)
}
end

但我得到了这个错误:

ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  syntax error at or near "1")
LINE 2:       AND permission_activity.permission_id IN 1,2,3) LIMIT ...

为什么permissions没有显示为数组?我是不是错过了一些显而易见的东西?还是我的方法从概念上就注定了?

有用信息:

class Permission < ApplicationRecord
has_many :permission_activities, dependent: :destroy
has_many :activities, through: :permission_activities
end
class Activity < ApplicationRecord
has_many :permission_activities, dependent: :destroy
has_many :permissions, through: :permission_activities
end
class PermissionActivity < ApplicationRecord
belongs_to :permission
belongs_to :activity
end

大部分查询不需要使用字符串:

class PermissionActivity < ApplicationRecord
belongs_to :permission
belongs_to :activity
def self.allowed_access(permissions, url, method)
includes(:activity)
.where("? ~ activities.url_regex", url)
.where(
activities: { 
method: method
},
permission_activities: {
permission_id: permissions
} 
})
end
end

当您将调用链接到where时,它将把条件与AND连接起来,当您传递条件哈希时也是如此。

不要为多行方法使用scope——这只是创建类方法时被过度使用的语法糖。该文档是极其错误的——除了singleton_class.define_method ...之外,它绝对是蹲着的,如果你设法砸到了什么东西,它就会上升。按照惯例,它用于声明查询数据库的方法。它会使代码更难阅读,并对静态分析隐藏该方法。

如果您确实创建了多行lambda,请使用do ... end,而不是像块那样使用大括号。

这里有几个问题:

  1. ~(在原始查询中(可以使用正则表达式,而LIKE则不能
  2. SQL中的表名应该是复数,而不是像您那样的单数
  3. 您正在询问的IN问题

修复第一个很容易:用~替换LIKE。固定第二个也很容易:使用复数。修复第三个也是非常直接的:IN想要一个列表,所以在命名的占位符周围添加一些括号。

应用这些给你:

scope :allowed_access, lambda { |permissions, url, method|
includes(:activity).where(
'activities.method = :method AND :url ~ activities.url_regex
AND permission_activities.permission_id IN (:permissions)',
method: method, url: url, permissions: permissions
)
}

最新更新