Ruby on rails 活动记录:从PostgreSQL数组中删除元素
假设有一个名为Ruby on rails 活动记录:从PostgreSQL数组中删除元素,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,假设有一个名为Job的活动记录模型,它有一个数组列follower\u id。我已经创建了一个作用域,允许获取用户跟踪的所有作业: #返回后跟指定用户id的所有作业 def self.后跟(用户id) 在哪里( Arel::Nodes::InfixOperation.new( '@>', Job.arel_表[:follower_id], sql(“数组[#{user_id}]::bigint[]”) ) ) 结束 #检索id=1的用户后面的所有作业 作业。后跟(1) 是否有一种方法可以使用
Job
的活动记录模型,它有一个数组列follower\u id
。我已经创建了一个作用域,允许获取用户跟踪的所有作业:
#返回后跟指定用户id的所有作业
def self.后跟(用户id)
在哪里(
Arel::Nodes::InfixOperation.new(
'@>',
Job.arel_表[:follower_id],
sql(“数组[#{user_id}]::bigint[]”)
)
)
结束
#检索id=1的用户后面的所有作业
作业。后跟(1)
是否有一种方法可以使用数据库从follower\u id
列中删除特定元素(即,不在活动记录对象中循环并手动调用删除/保存)
例如,执行类似于Job.follower(1).remove\u follower(1)
的操作会很好,只需一个查询就可以从所有这些作业的follower\u id
中删除id=1的用户。我认为这确实是一个XY问题,因为您使用的是一个数组列,而您应该使用联接表
您不想使用数组的主要原因是:
- 如果用户被删除,则必须更新jobs表中的每一行,而不是通过级联或删除回调删除join表中的行
- 没有引用完整性
- 可怕的不可读的查询。它实际上只是一个逗号分隔字符串的边缘级
- 连接并没有那么昂贵。“过早优化是万恶之源”
- 不能对数组列使用ActiveRecord关联
使用rails g model创建连接模型,用户:references作业:references
。然后设置关联:
class Job < ApplicationRecord
has_many :followings
has_many :followers,
through: :followings,
source: :user
end
class User < ApplicationRecord
has_many :followings
has_many :followed_jobs,
source: :job,
through: :followings,
class_name: 'Job'
end
若要获取未遵循的作业,请对以下项执行外部联接,其中用户id为零或不等于user\u id
fui = Following.arel_table[:user_id]
Job.left_joins(:followings)
.where(fui.eq(nil).or(fui.not_eq(1)))
如果要取消作业,只需从以下中删除该行即可:
Following.find_by(job: job, user: user).destroy
# or
job.followings.find_by(user: user).destroy
# or
user.followings.find_by(job: job).destroy
当使用相关:
选项销毁作业或用户时,您可以使用自动执行此操作。我使用PostgreSQL函数结束,该函数允许从数组中删除值,如下所示:
user\u id=1
update_query=感谢您提供此代码片段,它可能会提供一些有限的即时帮助。通过展示为什么这是一个很好的问题解决方案,A将极大地提高它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的回答中添加一些解释,包括您所做的假设。
Following.find_by(job: job, user: user).destroy
# or
job.followings.find_by(user: user).destroy
# or
user.followings.find_by(job: job).destroy