0

次のサブスクリプション作成システムがあります。現在、利用可能なサブスクリプショングループ(マーケティング、販売)を選択するとSave Subscription、次の2つのサブスクリプションが作成されます。

@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)destroy 後のサブスクリプションにコールバックを持たないのはなぜですか?

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 に答える