Установить атрибут модели из сервиса - PullRequest
0 голосов
/ 17 января 2019

Я впервые пользуюсь услугами 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, если это возможно.

Не могли бы вы указать мне?

EDIT:

на мой взгляд (новый):

= 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

1 Ответ

0 голосов
/ 17 января 2019

Вы пытаетесь получить доступ к полю модели discounted_price_pretax_cents на сервисном объекте, у которого нет этого поля.

Если PricingComputed как сервисный объект (объект, который выполняет бизнес-логику), вам, вероятно, не следует передавать его в представление. Вместо этого создайте объект данных (например, Struct) с данными, которые необходимы в представлении, или передайте модель (в этом случае, вероятно, @order).

Вы также можете обернуть @order в декоратор, который будет преобразовывать значения и настраивать его так, чтобы они отображались в виде, но я думаю, что это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...