我尝试根据一些条件删除数据库中的多条记录。在我谈论我的问题之前,我将解释我的应用程序是如何工作的。
用户可以创建组和链接。此用户拥有他为链接创建的组。然后,其他用户可以通过成员模型提供令牌(在创建组时自动创建)来加入此组。其中成员在DB中具有user_id和group_id。然后,一旦用户成为组的一部分,他就可以通过Grouplink模型共享他在组中创建的链接。其中grouplink有groupd_id和link_id。
我设法编写了一个事实,即如果一个组中没有成员,该组就会被销毁。但是,如果用户离开群组,如何删除用户在群组中共享的链接? (当用户被自动销毁时,所有链接都被删除,所以我认为共享应该也已经消失了,我必须尝试那样做)。当用户离开该组时,我会销毁他的会员记录,但他已经离开,但链接仍然存在。我显示共享链接,你可以踢用户(成员销毁)和组中的组成员列表显示顺便说一句。
我想到了一些事情。我写下我在控制台中所做的事情
g = Group.find(66)
u = g.users.find(1)
u.links
,它会给我组中用户的所有链接。在那旁边
g.grouplinks
会给我组中的所有共享链接。
g.grouplinks.map(&:link_id) returns [16, 17, 14, 13, 15]
u.links.map(&:id) returns [13, 15]
现在我该怎么办?我的用户正在离开小组。会员记录被销毁,我如何根据用户的链接销毁这些群组链接? 是否有一个我不知道的魔术?
感谢您的帮助。
编辑
class User < ApplicationRecord
has_secure_password
has_many :links, dependent: :destroy
has_many :grouplinks, dependent: :destroy
has_many :members, :dependent => :destroy
has_many :groups, :through => :members
has_one :owned_group, foreign_key: "owner_id", class_name: "Group"
end
class Member < ApplicationRecord
belongs_to :user
belongs_to :group
validates :user_id, :presence => true
validates :group_id, :presence => true
validates :user_id, :uniqueness => {:scope => [:user_id, :group_id]}
end
class Link < ApplicationRecord
has_many :grouplinks, :dependent => :destroy
belongs_to :user
end
class Grouplink < ApplicationRecord
belongs_to :group
belongs_to :link
end
class Group < ApplicationRecord
has_secure_token :auth_token
has_many :members, :dependent => :destroy
has_many :users, through: :members, source: :user
belongs_to :owner, class_name: "User"
has_many :links, through: :grouplinks
has_many :grouplinks, :dependent => :destroy
def to_param
auth_token
end
end
我认为实际上我可以在grouplinks中添加user_id,因此我可以根据链接和groupslinks中的user_id删除all_all。不知道如何做到这一点&#39;并且不知道是否有更好的解决方案。
编辑2
我在模型中尝试了你的解决方案。实际上它很聪明,我没有想到...... 现在问题是我的grouplink的创建(共享链接)。我有这个:
def create
user = current_user if current_user
group = user.groups.find_by(auth_token: params[:auth_token])
share = group.id
group_link = group.grouplinks.build(link_id: params[:link_id])
gl = group.grouplinks
if gl.where(group_id: share).where(link_id: params[:link_id]).exists?
flash[:error] = "You shared this link in '#{group.name}' already."
redirect_to mylinks_path
else
if group_link.save
group_link.toggle!(:shared)
flash[:success] = "You shared your link in '#{group.name}'."
redirect_to mylinks_path
else
render 'new'
end
end
end
这显然不再适用了,当我尝试分享链接时出现此错误:First argument in form cannot contain nil or be empty
<%= form_for @grouplink do |f| %>
。
我试着改变它:
def create
group = Group.find_by(auth_token: params[:auth_token])
share = group.id
group_link = group.grouplinks.build(link_id: params[:link_id])
gl = group.grouplinks
if gl.where(group_id: share).where(link_id: params[:link_id]).exists?
flash[:error] = "You shared this link in '#{group.name}' already."
redirect_to mylinks_path
else
if group_link.save
group_link.toggle!(:shared)
flash[:success] = "You shared your link in '#{group.name}'."
redirect_to mylinks_path
else
render 'new'
end
end
end
但它不起作用
答案 0 :(得分:2)
怎么样:
class Member < ApplicationRecord
belongs_to :user
belongs_to :group
has_many :group_links, dependent: :destroy
validates :user_id, :presence => true
validates :group_id, :presence => true
validates :user_id, :uniqueness => {:scope => [:user_id, :group_id]}
end
和
class Grouplink < ApplicationRecord
belongs_to :link
belongs_to :member
end
现在,当Member
记录被销毁时(即,user
被踢出或离开group
),任何links
与{{1}共享(即,group
)也被销毁。但是,如果group_links
在另一个user
中共享了link
,则group
将继续与其他link
共享。
正如@Pablo在评论中所提到的,你可能也想这样做:
groups
允许您这样做:
class Group < ApplicationRecord
has_secure_token :auth_token
has_many :members, :dependent => :destroy
has_many :grouplinks, through: :members
has_many :users, through: :members, source: :user
belongs_to :owner, class_name: "User"
has_many :links, through: :grouplinks
def to_param
auth_token
end
end
我也同意@ amr-el-bakry group.grouplinks
有点令人困惑。我建议使用Member
,因为它很清楚它是GroupUser
和Group
之间的关联。
另外,我认为说User
而不是GroupLink
可能更常规一些。或者,如果您想坚持基于关联类的命名,可能Grouplink
。如果您将MemberLink
更改为Member
,那么可能会GroupUser
。
我认为您的GroupUserLink
代码应该类似于:
create
你可能能够将其写成:
def create
if group
if member
if link
unless group_link
@group_link = member.group_links.build(link: link)
if group_link.save
group_link.toggle!(:shared)
flash[:success] = "You shared your link in '#{group.name}'."
redirect_to mylinks_path
else
render :new
end
else
flash[:error] = "You shared this link in '#{group.name}' already."
else
flash[:error] = "That link does not exist."
redirect_to somewhere #fix this
end
else
flash[:error] = "You must be a member of this group to add a link."
redirect_to somewhere #fix this
end
else
flash[:error] = "There is no group with that token."
redirect_to somewhere #fix this
end
end
private
def group
@group ||= Group.find_by(auth_token: params[:auth_token])
end
def member
@member ||= current_user.members.where(group: group)
end
def link
@link ||= Link.find_by(id: params[:link_id])
end
def group_link
@group_link ||= member.group_links.where(link: link)
end
但是我不记得那些重定向会让你心痛。
答案 1 :(得分:1)
您正在寻找的是Group
在您的has_many :links, dependent :delete_all
模型中,您希望自己应该有一行:
SortedCollection = inputCollection.stream()
.map(e -> {
return new Element(e.id, e.color);
}).collect(Collectors.toList());
这就是说,该组有许多链接,如果您销毁该组,则销毁所有相关链接。
答案 2 :(得分:1)
在您的Member
模型中,您可以使用after_destroy
回调在销毁会员记录后销毁该组中的所有用户链接:
class Member < ApplicationRecord
after_destroy do |record|
record.user.links.each { |link| link.grouplinks.where(group_id: record.group.id).destroy_all }
end
belongs_to :user
belongs_to :group
...
end
此外,我建议您将Member
更改为Membership
以便更清楚。
答案 3 :(得分:0)
我认为最好的想法是group_links属于成员和链接(而不是组和链接)。并且成员(不是用户)具有许多group_links。当你破坏成员时,它会破坏group_links。
修改强>
这就是jvillian在我的回答中提出的,就在我做之前。所以我相信他的答案是正确的(我在评论中提出了一些小的改进,jvillian肯定会接受并补充: - )。
<强> EDIT2 强>
关于在应用jvillian建议后遇到的问题,在创建新的grouplink时,必须从成员(不是组)完成。因此,在创建操作中,您必须搜索成员(通过user_id和group_id)并将grouplink创建为member.grouplinks.build