我想干掉我的控制器,因为我在同一个控制器内多次使用一些片段/代码块(我删除了一些,因为它太长了但是这已经给出了重复的想法)。以下是我不断重复的方块:
@deal = search_deal
@next_deal = find_next_deal
@userdeal = find_or_create_userdeal_participation
@user_credits = calculate_user_credits_in_deal
我很新秀并且不知道如何做到这一点,但我觉得这段代码应该被分解。
class DealsController < ApplicationController
before_filter :find_deal,
:only => [ :showcase ]
before_filter :ensure_canonical_deal_path!,
:only => [ :showcase ]
def showcase
# find appropriate deal
@deal = search_deal
respond_to do |format|
format.html # showcase.html.erb
format.json { render json: @deal }
end
end
def buy_stuff
@deal = search_deal
# bring 'next deal' url to the view
@next_deal = find_next_deal
# USER IS SIGNED-IN
if user_signed_in?
@userdeal = find_or_create_userdeal_participation
@user_credits = calculate_user_credits_in_deal
# if: user still has credits available
if @user_credits >= 1
#do this
respond_to do |format|
format.js
end
else
respond_to do |format|
# do that
end
end
# USER IS NOT SIGNED-IN
else
respond_to do |format|
format.js { render :template => "deals/call_to_sign_in.js.erb" }
end
end
end
def show_discounts
@deal = search_deal
respond_to do |format|
#do that
end
end
def pending_deals
@deal = search_deal
# bring 'next deal' url to the view
@next_deal = find_next_deal
if user_signed_in?
@userdeal = find_or_create_userdeal_participation
@user_credits = calculate_user_credits_in_deal
end
respond_to do |format|
#do this
end
end
def ask_question
@deal = search_deal
respond_to do |format|
#do that
end
end
protected
def ensure_canonical_deal_path!
if request.path != actual_deal_page_path(@deal)
redirect_to actual_deal_page_path(@deal, :format => params[:format]), :status => :moved_permanently
return false
end
end
private
# DRY file as this is used multiple times
# trick source - http://blog.rstankov.com/rails-anti-pattern-setting-view-variables-in-before-actions/
def search_deal
Deal.friendly.find(params[:id])
end
def find_or_create_userdeal_participation
UserDeal.where('user_id = ? AND deal_id = ?', current_user.id, @deal.id).take ||
UserDeal.create(user_id: current_user.id, deal_id: @deal.id)
end
def calculate_user_credits_in_deal
current_user.credit_nb + @userdeal.history
end
def find_next_deal
Deal.order_next_deal_at(@deal).next
end
end
答案 0 :(得分:1)
我认为最好的方法就是为那些调用重复代码的方法添加before_filters,如:
before_filter :search_deal, :only => [:showcase, :buy_stuff, ...]
答案 1 :(得分:0)
class DealsController < ApplicationController
before_filter :find_deal, only: [:showcase]
before_filter :ensure_canonical_deal_path!, only: [:showcase]
def showcase
search_deal
respond_to do |format|
format.html
format.json{render json: @deal}
end
end
def buy_stuff
search_deal
find_next_deal
if user_signed_in?
find_or_create_userdeal_participation
calculate_user_credits_in_deal
if @user_credits >= 1
respond_to(&:js)
else
respond_to{|format| }
end
else
respond_to{|format| format.js{render template: "deals/call_to_sign_in.js.erb"}}
end
end
def show_discounts
search_deal
respond_to{|format|}
end
def pending_deals
search_deal
find_next_deal
if user_signed_in?
find_or_create_userdeal_participation
calculate_user_credits_in_deal
end
respond_to{|format| }
end
def ask_question
search_deal
respond_to{|format| }
end
protected def ensure_canonical_deal_path!
if request.path != actual_deal_page_path(@deal)
redirect_to actual_deal_page_path(@deal, format: params[:format]), status: :moved_permanently
return false
end
end
private def search_deal
@deal = Deal.friendly.find(params[:id])
end
private def find_or_create_userdeal_participation
@user_deal =
UserDeal.where('user_id = ? AND deal_id = ?', current_user.id, @deal.id).take ||
UserDeal.create(user_id: current_user.id, deal_id: @deal.id)
end
private def calculate_user_credits_in_deal
@user_credits = current_user.credit_nb + @userdeal.history
end
private def find_next_deal
@next_deal = Deal.order_next_deal_at(@deal).next
end
end