ruby-on-rails - 重构讨厌的 Rails 控制器
问题描述
我一直在向控制器添加一些“盲目”的东西,目前一切正常,但控制器变得非常混乱。我正在使用 gemrails_best_practices
来整理我的代码,但除了将一些方法从控制器移动到模型之外,它目前没有给我任何其他修复。
几个问题
是否有其他类似
rails_best_practices
的宝石可以用来弄清楚如何整理控制器?
其次
关于我应该在这里做什么样的改变有什么建议吗?
我在这里做一些授权,我认为我应该使用 gem 来处理,但目前没有使用任何授权 gem。
这是混乱
class OffersController < ApplicationController
before_action :authenticate_user!
before_action :offer_authorised, only: [:show]
before_action :set_offer, only: [:accept, :reject, :send_signature_requests, :make_payment]
before_action :is_authorised, only: [:accept, :reject]
def create
session[:return_to] ||= request.referer
if !current_user.stripe_id?
return redirect_to payment_path, alert: "Connect your bank accout before payments."
end
rental = Rental.find(offer_params[:rental_id])
if rental && rental.user_id == current_user.id
redirect_to(request.referrer, alert: "You cannot make an offer from your own property.") && return
end
if current_user.offers.accepted.any?
redirect_to(request.referrer, alert: "You've already rented an apartment.") && return
end
if Offer.exists?(user_id: current_user.id, rental_id: offer_params[:rental_id])
redirect_to(request.referrer, alert: "You can only make one offer at a time.") && return
end
@offer = current_user.offers.build(offer_params)
@offer.landlord_id = rental.user.id
if @offer.save
redirect_to applications_path, notice: "Offer sent."
else
redirect_to request.referrer, flash: {error: @offer.errors.full_messages.join(", ")}
end
end
def destroy
@offer = Offer.find(params[:id])
@offer.destroy
redirect_to request.referrer, notice: "Offer deleted."
end
def accept
if @offer.waiting?
@offer.accepted!
@offer.rental.update(active: !@offer.rental.active?)
Offer.where(landlord_id: current_user.id, rental_id: @offer.rental.id).where.not(id: @offer.id).update_all(status: 2)
@offer.rental.tours.destroy_all
@offer.user.tours.destroy_all
OfferMailer.with(offer: @offer, tenant: @offer.user_id, landlord: @offer.landlord_id).offer_accepted.deliver_now
flash[:notice] = "Offer accepted."
end
redirect_to offer_accepted_path(@offer)
end
def reject
if @offer.waiting?
@offer.rejected!
flash[:notice] = "Offer rejected."
end
redirect_to request.referrer
end
def update
@offer = Offer.find(params[:id])
if params[:offer][:due_date]
@offer.update(due_date: params[:offer][:due_date])
end
if params[:offer][:rental_agreement]
@offer.rental_agreement.purge
@offer.rental_agreement.attach(params[:offer][:rental_agreement])
end
flash[:notice] = "Saved."
redirect_to request.referrer
end
def show
@offer = Offer.find(params[:id])
@rental = @offer.rental_id ? Rental.find(@offer.rental_id) : nil
@comments = Comment.where(offer_id: params[:id])
@has_attachment_file_sent = Comment.where(user_id: @offer.landlord_id).any? { |obj| obj.attachment_file.attached? }
respond_to do |format|
format.html
format.js { render layout: false }
end
end
def pay_rent
@offer = Offer.find(params[:id])
@rental = @offer.rental_id ? Rental.find(@offer.rental_id) : nil
if @rental.user_referral_reward_count > 0
referral_rent_payment(@rental, @offer)
else
make_payment(@rental, @offer)
end
flash[:notice] = "Payment succeeded."
redirect_to request.referrer
end
def send_signature_requests
landlord_mail = User.where(id: @offer.landlord_id)[0].email
tenant_mail = User.where(id: @offer.user_id)[0].email
if @offer.rental_agreement.attached?
attachment_file = @offer.rental_agreement
blob_path = rails_blob_path(attachment_file, disposition: "attachment", only_path: true)
response = HTTParty.get("URL", body: {
landlord_mail: landlord_mail,
tenant_mail: tenant_mail,
agreement_url: blob_path
}.to_json,
headers: {"Content-Type" => "application/json"})
@offer.update(invitation_uuid: response.parsed_response["invitation_uuid"], document_uuid: response.parsed_response["document_uuid"])
flash[:notice] = "Signature requests sent."
redirect_to request.referrer
else
flash[:alert] = "Add aggreement."
redirect_to request.referrer
end
rescue => e
flash[:alert] = "Failed to send signature requests."
redirect_to request.referrer
end
private
def make_payment(rental, offer)
unless offer.user_stripe_id.blank?
payment_methods = Stripe::PaymentMethod.list(
customer: offer.user_stripe_id,
type: "sepa_debit"
)
payment_intent = Stripe::PaymentIntent.create({
payment_method_types: ["sepa_debit"],
payment_method: payment_methods.data[0].id,
confirm: true,
off_session: true,
customer: offer.user_stripe_id,
amount: offer.amount * 100,
currency: "eur",
application_fee_amount: offer.amount * 4,
metadata: {"name" => User.where(id: offer.user_id).first.full_name, "offer" => offer.id},
transfer_data: {
destination: rental.user_merchant_id
}
})
end
rescue Stripe::CardError => e
flash[:alert] = e.message
end
def referral_rent_payment(rental, offer)
unless offer.user_stripe_id.blank?
referrer = User.find_by(id: rental.user.id)
customer = Stripe::Customer.retrieve(offer.user_stripe_id)
charge = Stripe::Charge.create(
customer: customer.id,
amount: offer.amount * 100,
description: "Rent for #{rental.listing_name}",
currency: "eur",
application_fee_amount: offer.amount * 2,
metadata: {"name" => User.where(id: offer.user_id).first.full_name, "offer" => offer.id},
transfer_data: {
destination: rental.user_merchant_id
}
)
referrer.update_attribute(:referral_reward_count, referrer.referral_reward_count -= 1)
end
rescue Stripe::CardError => e
flash[:alert] = e.message
end
def offer_authorised
unless Offer.exists?(["id = ? AND (landlord_id = ? OR user_id = ?) AND status = ?", params[:id], current_user.id, current_user.id, 1])
redirect_to dashboard_path,
alert: "You're not authorized."
end
end
def set_offer
@offer = Offer.find(params[:id])
end
def is_authorised
redirect_to root_path, alert: "You're not authorized." unless current_user.id == @offer.rental.user_id
end
def offer_params
params.require(:offer).permit(:amount, :rental_id, :status, :priority, :rental_agreement)
end
end
解决方案
那么你可以试试reek gem 它有助于检测代码中的气味。
推荐阅读
- node.js - 我想要用户获得的分数
- ios - 如何找到一个时区的所有历史偏移转换日期?
- bash - 在 bash 脚本中使用不同的文件扩展名进行循环
- javascript - .$ 在 javascript 中是什么意思
- python - 如何将过滤器应用于 Python 脚本以下载特定的电子邮件附件
- c# - 创建多个实例时,用户控件中未触发单击事件
- windows - 无法访问 Jfrog UI - jfrog-artifactory-oss-7.21.5
- c# - 如何断言构造函数中抛出的异常?
- swift - 如何在swift中存储带有约束的序列变量
- javascript - 如何在 Angular App 中保存用户活动?