如何使用一个控制器操作管理多个订阅?

时间:2012-11-06 18:14:32

标签: ruby-on-rails ruby-on-rails-3 model-view-controller

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

Subscriptions

如何重构该操作以通过取消选中来销毁订阅组(例如,我想取消订阅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)

删除Feed

1 个答案:

答案 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 ...用户如何获得未获批准的订阅?想想那样。他们没有选择点击他们没有显示的那些,对吗?这是一个他们必须付钱才能得到某些东西的问题吗?

决定用户是否能够订阅某些东西不应该在控制器级别发生。因此,我想说在订阅中放置一个回调,不允许为未经授权的用户保存,然后如果用户保存或不保存,则可以回复,如果没有,则显示用户错误。