0

我有以下订阅创建系统,现在当我选择可用订阅组(营销、销售)操作时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

订阅

如何重构该操作,以便能够通过取消选中订阅组来销毁订阅组(例如,我想从营销组取消订阅)?

所以当我选择营销工程时,那就是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)

4

1 回答 1

1

好的,所以在您的情况下,订阅是应用程序和用户之间的连接模型。这意味着您可以像这样看到用户的应用程序:

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

但是,在我看来,您的控制器在这里变得愚蠢。为什么不在模型层处理更多的这些?

例如 for Feed.app_destroy_items(app),为什么在销毁后订阅中没有回调呢?

after_destroy :destroy_app_from_feed
def destroy_app_from_feed
  Feed.app_destroy_items(app)
end

至于设置approved=true......用户如何获得未批准的订阅?这样想吧。他们没有选择单击未显示的选项,对吗?这是他们必须付费才能获得某些东西的问题吗?

几乎不应该在控制器级别决定用户是否能够订阅某些内容。所以,我会说在订阅中放置一个回调,不允许为未经授权的用户保存它,然后您可以响应用户是否保存,如果没有,则显示用户错误。

于 2012-11-06T23:02:45.957 回答