我有以下订阅创建系统,现在当我选择可用订阅组(营销,销售)时,Save Subscription
创建这两个订阅:
@apps = App.all
if request.post?
if params[:subscription] and params[:subscription][:app_id]
params[:subscription][:app_id].each do |app_id|
Subscription.create_unique({user_id: current_user.id, app_id: app_id, approved: true})
end
redirect_to root_path
end
end
@subscriptions = current_user.subscriptions
所以我只能添加新Subscriptions
(在此特定示例中,我只能添加Engineering
)
如何重构该操作以通过取消选中来销毁订阅组(例如,我想取消订阅Marketing组)?
因此,当我选择营销和 Enginnering 时,params[:subscription][:app_id]
将等于[marketing.id, engineering.id]
# app_menu.html.erb
<%= form_for :subscription do |f| %> # this form goes to app_menu action above
<ul>
<% @apps.each do |app| %>
<li>
<%= check_box_tag app.id, current_user.access?(app) %><span><%= app.name %></span>
</li>
<% end %>
</ul>
<%= f.submit %>
<% end %>
<% end %>
关系:
App
has_many :subscriptions
has_many :users, through: :subscriptions
User
belongs_to :app
has_many :subscriptions, :dependent => :destroy
Subscription
belongs_to :user
belongs_to :app
def self.create_unique(p)
s = Subscription.find :first, :conditions => ['user_id = ? AND app_id = ?', p[:user_id], p[:app_id]]
Subscription.create(p) if !s
end
模式
# == Schema Information
#
# Table name: subscriptions
#
# admin :boolean
# app_id :integer
# created_at :datetime
# id :integer not null, primary key
# updated_at :datetime
# user_id :integer
#
# Table name: apps
#
# created_at :datetime
# id :integer not null, primary key
# name :string(255)
# updated_at :datetime
# user_id :integer
#
# Table name: users
#
# app_id :integer
# created_at :datetime
# id :integer not null, primary key
# updated_at :datetime
所以问题是如何找到哪些应用已被取消选中?
然后删除订阅并使用Feed.app_destroy_items(app)
答案 0 :(得分:1)
好的,所以在你的情况下,Susbcription是App和User之间的连接模型。这意味着你可以看到用户的应用程序如下:
user.apps # returns array of apps
这意味着您也可以以相同的方式设置它们。所以这样的事情应该有效:
if params[:subscription] and params[:subscription][:app_ids] #call it app_ids since you're getting an array of them.
apps = App.find(params[:subscription][:app_ids])
current_user.apps = apps
else
current_user.apps = []
end
current_user.save
因为订阅是一个连接模型,并且你已经在两端链接了它,所以在大多数情况下你并不需要直接加载模型。
上面已更新,显示处理取消选中所有应用的处理。
回应评论:
如果您需要了解新旧应用之间的区别,可以执行以下操作:
original_apps = current_user.apps
... the code from above ...
deleted_apps = original_apps - current_user.apps
deleted_apps.each do |app|
... whatever ...
end
然而,在我看来,你的控制器在这里变得愚蠢。为什么不在模型层处理更多这个?
例如,对于Feed.app_destroy_items(app)
,为什么在销毁之后没有订阅回调?
after_destroy :destroy_app_from_feed
def destroy_app_from_feed
Feed.app_destroy_items(app)
end
至于设置approved=true
...用户如何获得未获批准的订阅?想想那样。他们没有选择点击他们没有显示的那些,对吗?这是一个他们必须付钱才能得到某些东西的问题吗?
决定用户是否能够订阅某些东西不应该在控制器级别发生。因此,我想说在订阅中放置一个回调,不允许为未经授权的用户保存,然后如果用户保存或不保存,则可以回复,如果没有,则显示用户错误。