这是我第一次使用Rails服务。更改之前,我的代码令人担忧。
问题在于,在我的一种方法中,我必须设置模型属性,但不确定如何从服务中执行此操作。
在我的控制器中:
def new
@order = Order.new(default_order_create_params)
@pricing = PricingComputed.new(order: @order, user: current_user)
end
从我的服务中(我删除了不必要的代码):
# frozen_string_literal: true
class PricingComputed
def initialize(params)
@order = params[:order]
@user = params[:user]
end
def perform
set_discounted_price_pretax_cents
end
private
def set_discounted_price_pretax_cents
return unless @order.pending?
@order.discounted_price_pretax_cents = @order.price_pretax_cents - discount_cents
end
end
我希望能够设置discounted_price_pretax_cents
并从@pricing
中使用它。
你能指出我吗?
编辑:
在我看来(新):
= render('steps/price_card', order: @order, pricing: @pricing)
_price_card:
#order-price-card.neo-card
.neo-card-heading
h2.neo-card-title
| Your order
- if order.cash?
.neo-card-price-reduction
.neo-card-list-item
.neo-card-list-item-label
| Your reduction
.neo-card-list-item-value
- if pricing.discount_cents.positive?
strong
=> number_to_currency(pricing.discount)
small
= "(#{number_to_percentage(pricing.discount_percent, precision: 2)})"
- else
strong> 0.00$
small
| (0.00%)
p.small Order more words for a better discount
.neo-card-price-total
.neo-card-price-total-label Total
.neo-card-price-total-value
- if order.credits?
.neo-card-price-total-value-pretax
- if order.credits.positive?
=> order.credits
small credits
- else
' 0
small credit
- else
.neo-card-price-total-value-pretax
=> number_to_currency(pricing.discounted_price_pretax_cents)
small HT
.neo-card-price-total-value-tax
=> number_to_currency(order.price)
small TTC
- if user_signed_in? && order.new_record?
.neo-card-credits-link
= link_to(\
"Buy credits",
new_credit_pack_path)
日志:
09:50:47 server.1 | Started GET "/steps/orders/new" for ::1 at 2019-01-17 09:50:47 +0100
09:50:48 server.1 | Processing by Steps::OrdersController#new as HTML
09:50:48 server.1 | User Load (1.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 7], ["LIMIT", 1]]
09:50:48 server.1 | ↳ app/controllers/application_controller.rb:93
09:50:49 server.1 | Category Load (0.6ms) SELECT "categories".* FROM "categories" ORDER BY "categories"."id" ASC LIMIT $1 [["LIMIT", 1]]
09:50:49 server.1 | ↳ app/controllers/steps/orders_controller.rb:18
09:50:49 server.1 | Rendering steps/orders/new.html.slim within layouts/new_order
09:50:49 server.1 | User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 7], ["LIMIT", 1]]
09:50:49 server.1 | ↳ app/views/steps/orders/new.html.slim:31
09:50:49 server.1 | Category Load (0.4ms) SELECT "categories"."id", "categories"."source_language", "categories"."target_language" FROM "categories"
09:50:49 server.1 | ↳ app/helpers/orders_helper.rb:33
09:50:49 server.1 | (0.4ms) SELECT "categories"."source_language" FROM "categories"
09:50:49 server.1 | ↳ app/helpers/orders_helper.rb:29
09:50:49 server.1 | Category Load (0.6ms) SELECT "categories".* FROM "categories" WHERE "categories"."source_language" = $1 [["source_language", "fr"]]
09:50:49 server.1 | ↳ app/views/steps/orders/new.html.slim:60
09:50:49 server.1 | Rendered steps/_price_card.slim (15.2ms)
09:50:49 server.1 | Rendered steps/orders/new.html.slim within layouts/new_order (45.7ms)
09:50:49 server.1 | Completed 500 Internal Server Error in 1203ms (ActiveRecord: 21.5ms)
09:50:49 server.1 |
09:50:49 server.1 |
09:50:49 server.1 | undefined method `discounted_price_pretax_cents' for #<PricingComputed:0x00007fd8cb7c5f28> excluded from capture: Not configured to send/capture in environment 'development'
09:50:49 server.1 |
09:50:49 server.1 | ActionView::Template::Error (undefined method `discounted_price_pretax_cents' for #<PricingComputed:0x00007fd8cb7c5f28>):
09:50:49 server.1 | 31: small credit
09:50:49 server.1 | 32: - else
09:50:49 server.1 | 33: .neo-card-price-total-value-pretax
09:50:49 server.1 | 34: => number_to_currency(pricing.discounted_price_pretax_cents)
09:50:49 server.1 | 35: small HT
09:50:49 server.1 | 36: .neo-card-price-total-value-tax
09:50:49 server.1 | 37: => number_to_currency(order.price)
09:50:49 server.1 |
09:50:49 server.1 | app/views/steps/_price_card.slim:34:in `_app_views_steps__price_card_slim__802419931166157136_70284550345380'
09:50:49 server.1 | app/views/steps/orders/new.html.slim:73:in `_app_views_steps_orders_new_html_slim__4387080387746709579_70284551781060'
此外,价格会在值更改时更新:
function updatePriceCard() {
const $form = $('#order-form');
$.ajax('/orders/estimate_prices', {
data: $form.find('textarea, select, input:not([name="_method"])').serialize(),
type: 'POST',
}).done((data) => {
$('#order-price-card').replaceWith(data);
});
}
def estimate_prices
@order =
if params[:id].present? then Order.find(params[:id])
else Order.new
end
@order.assign_attributes(
order_params.merge(user: current_user)
)
@pricing = PricingComputed.new(@order).perform
render(partial: 'steps/price_card', layout: false, locals: {
order: @order, pricing: @pricing
})
end
答案 0 :(得分:2)
您尝试访问不具有模型字段discounted_price_pretax_cents
的服务对象。
如果PricingComputed
作为服务对象(运行业务逻辑的对象),则可能不应将其传递给视图。而是使用视图中所需的数据构建数据对象(例如Struct
),或传递模型(在这种情况下,可能是@order
)。
您还可以将@order
包装在一个装饰器中,该装饰器将转换值并对其进行调整以在视图中显示它们,但我认为这里不是这种情况。