所以我试图在发票页面上建立past_due_amount,我试图只查找当前帐户的发票,这些发票没有付清,应该是过去的。
我粗略地说:
past_due_amount = Invoice.where(account: invoice.account, status: :unpaid).where('date < ? ', invoice.date).map(&:due).sum
有关其他背景,请参阅以下模型:
发票:
class Invoice < ApplicationRecord
belongs_to :account
has_many :line_items, dependent: :destroy
has_many :payment_destinations, dependent: :destroy
has_many :prorated_fees, dependent: :nullify
enum status: [:unpaid, :paid]
validates :date, presence: true
validates :period_start, :period_end,
uniqueness: { scope: :account, allow_blank: true }, on: :create
validate :start_is_before_end
DAYS_DUE_AFTER_DATE = 14.days
scope :descending, -> { order(date: :desc) }
scope :ascending, -> { order(date: :asc) }
scope :due, -> { unpaid.where(arel_table[:date].lteq(Time.zone.today - DAYS_DUE_AFTER_DATE)) }
def total
if persisted?
line_items.sum(:amount)
else
line_items.map(&:amount).sum
end
端 端
帐户:
class Account < ApplicationRecord
belongs_to :customer
belongs_to :property_address,
class_name: Address.to_s,
dependent: :destroy,
required: false
[:products, :account_changes, :equipments,
:payments, :invoices].each do |assoc|
has_many assoc, dependent: :destroy
end
accepts_nested_attributes_for :property_address
delegate :street, :city, :state, :zip,
to: :property_address, allow_nil: true
delegate :email, :full_name, to: :customer
enum status: [:staged, :active, :inactive]
scope :active_or_staged, -> { where(status: [:staged, :active]) }
scope :past_due, lambda {
joins(:invoices)
.where(
Invoice.arel_table[:status].eq(:unpaid)
.and(Invoice.arel_table[:date].lt(Time.zone.today - 14.days))
).distinct
}
scope :search, lambda { |term|
joins(:customer)
.where(
arel_table[:account_num].matches("%#{term}%")
.or(Customer.arel_search(term))
)
}
end
随着粗略的代码到位,我决定在show方法中的InvoicesController上构建一个实例变量,如下所示:
def show
@invoice = Invoice.find_by!(id: params[:id], account: current_customer.account_ids)
@account = @invoice.account
@past_due_amount = Invoice.where(account: @account, status: :unpaid).where('date < ?', @invoice.date).map(&:due).sum
end
没有出现任何错误,但由于我的例子充其量只是很差,所以没有说太多。但我的问题是......我真的应该把它放在帮助器而不是InvoicesController甚至模型中的show方法吗?
编辑:
我也试过加入我的发票模型:
def self.past_due_amount
Invoice.where(account: @account, status: :unpaid).where('date < ?', @invoice.date).map(&:due).sum
end
然后在我的InvoicesController中:
def show
@invoice = Invoice.find_by!(id: params[:id], account: current_customer.account_ids)
@account = @invoice.account
@past_due_amount = Invoice.past_due_amount
end
最终得到未定义的方法`date&#39;为@ invoice.date。
答案 0 :(得分:1)
最好的方法是在past_due_amount
InvoicesHelper
module InvoicesHelper
def past_due_amount
Invoice.where(account: @account, status: :unpaid).where('date <?', @invoice.date).map(&:due).sum
end
end
在你的控制器中只需初始化所有实例变量
def show
@invoice = Invoice.find_by!(id: params[:id], account: current_customer.account_ids)
@account = @invoice.account
end
在视图中,您应该使用:<%= past_due_amount >
来显示您的数据
答案 1 :(得分:1)
在Account
模型
def past_due_amount
invoices.map(&:due).sum
end
然后从视图中你可以全部@account.past_due_amount
。无需在控制器操作中创建额外的实例变量
答案 2 :(得分:0)
所以我有点使用帕特里克的答案,但实际上却失败了所以我转而将发票作为params。
辅助
module InvoicesHelper
def past_due_amount(invoice)
Invoice.where(account: invoice.account, status: :unpaid).where('date < ?', invoice.date).map(&:due).sum
end
end
然后在我看来:
<% if past_due_amount(invoice).positive? %>
<p><%= number_to_currency past_due_amount(invoice) %></p>
<% end %>