Должен ли я создавать несколько контроллеров или несколько методов обновления в одном контроллере? - PullRequest
0 голосов
/ 26 ноября 2018

Проблема: У меня есть контроллер, в котором я хочу разделить действие обновления на 3 отдельных действия обновления ... Обновление для всех параметров (за исключением других действий обновления), обновление для изменения статуса заказа (создано, отменено, начислено) и обновление для начисления (начисление происходит только после загрузки файла в заказ)

Вопрос: Можете ли вы помочь мне направить и указать, по какому маршруту я долженсобираетесь выполнить это?

Как мне сделать это наиболее эффективным и "правильным" способом?

  1. Должен ли я создать еще 2 контроллера (так какМне нужно 3 обновления), одно для изменения статуса заказа, другое для начисления платы, и они должны наследовать OrderController?

  2. Или есть способ иметь 3 действия обновления в одном контроллере?Я попробовал это, но не мог понять это

Вот как я «решил» это, но, кажется, он не работает слишком гладко, как иногда я замечаю, когда я загружаюфайл в порядке, он начинает зацикливаться и / или занимает больше времени, чем просто все это при одном определенном методе param:

  def update
    respond_to do |format|
      if @order.update(order_status)
        if user_signed_in?
          format.html { redirect_to ([@user, @order]), notice: 'Order was successfully order_status.' }
          format.json { render :show, status: :ok, location: @order }
        else
          format.html { render :edit }
          format.json { render json: @order.errors, status: :unprocessable_entity }
        end
      end
        if @order.update(order_charge)
          @amount = (@order.order_price).to_i * 100
          @amount_seller = (@order.order_price).to_i * 75
          if @order.update(order_charge)
            if current_user.seller?
                          charge = Stripe::Charge.create({
                            :amount      => @amount,
                            :description => 'Rails Stripe customer',
                            :currency    => 'usd',
                            :customer => @order.stripe_customer_token,
                            :destination => {
                              :amount => @amount_seller ,
                              :account => (@order.seller.stripe_token),
                            }
                          })
              @order.order_status = "charged"
              format.html { redirect_to ([@user, @order]), notice: 'Order was successfully uploaded.' }
              format.json { render :show, status: :ok, location: @order }
            else
              format.html { render :edit }
              format.json { render json: @order.errors, status: :unprocessable_entity }
            end
          end
        end
        if @order.update(order_params)
          if user_signed_in?
            format.html { redirect_to ([@user, @order]), notice: 'Order was successfully updated.' }
            format.json { render :show, status: :ok, location: @order }
          else
            format.html { render :edit }
            format.json { render json: @order.errors, status: :unprocessable_entity }
          end
          if buyer_signed_in?
            format.html { redirect_to ([@user, @order]), notice: 'Order was successfully updated.' }
            format.json { render :show, status: :ok, location: @order }
          else
            format.html { render :edit }
            format.json { render json: @order.errors, status: :unprocessable_entity }
          end
        end
      end
    end


  private

    def set_order
      @order = Order.find(params[:id])
    end


    def order_params
      params.require(:order).permit(:name, :email, :image, :video, :description)
    end

    def order_status
      params.require(:order).permit(:order_status)
    end

    def order_charge
      params.require(:order).permit(:video)
    end
...
end

Это технически работает, но не совсем быстро, или как я хочу.Когда я загружаю видео, оно дает мне сообщение order_status, потому что я меняю статус заказа, когда видео загружается.Но он все еще работает в том смысле, что создается заряд.

Кто-нибудь когда-либо создавал приложение, в котором ему требовалось несколько действий по обновлению под одним контроллером и моделью, и находил лучший способ сделать это?

Несмотря на то, что вышеприведенный код «работает», мне сказали, что он неэффективен, и мне нужно создать еще 2 контроллера, чтобы выполнить то, что я хочу сделать.Я подумал, что приду сюда, прежде чем обнародовать это, чтобы узнать мнение других людей на основе их опыта, если у них были похожие приложения с этой проблемой.

Или, может быть, помимо вышеупомянутых 1 и 2, у вас есть большеидеи?

(Операция обновления, описанная выше, не завершена, например, order_status. Но меня больше всего беспокоит то, как я должен это делать.)

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Я закончил тем, что делал это ... благодаря такому сообщению, которое я нашел ранее ...

Контроллер заказов: (отдельно от действия обновления:)

def charge_update
    respond_to do |format|
      @amount = (@order.order_price).to_i * 100
      @amount_seller = (@order.order_price).to_i * 75
      if @order.update(order_charge)
                      charge = Stripe::Charge.create({
                        :amount      => (@order.order_price).to_i * 100,
                        :description => 'Rails Stripe customer',
                        :currency    => 'usd',
                        :customer => @order.stripe_customer_token,
                        :destination => {
                          :amount => @amount_seller ,
                          :account => (@order.seller.stripe_token),
                        }
                      })
          @order.update_column(:order_status, 2)
          format.html { redirect_to ([@user, @order]), notice: 'Order was successfully uploaded.' }
          format.json { render :show, status: :ok, location: @order }
        else
          format.html { render :edit }
          format.json { render json: @order.errors, status: :unprocessable_entity }
        end
      end
  end

маршруты:

 resources :orders do
    member do
      patch :charge_update
      put :charge_update
    end
  end

И для загрузки в представлении:

<%= form_for([@listing, @order], :url => charge_update_order_path ) do |form| %>
...
<%= form.file_field :video %>
...
<%= form.submit "Upload", class: "btn btn-success"  %>

остаток контроллера: (частный раздел)

private

def order_charge
      params.require(:order).permit(:video, :order_status)
    end

Теперь действие по загрузке видео является отдельным иработает быстрееЯ не сделал то же самое для обновления статуса заказа, чтобы отменить, что я могу или не могу после проведения дополнительного тестирования.Аспект зарядки был самым важным, чтобы отделить его от остальных параметров.

0 голосов
/ 26 ноября 2018

Один из способов решения этой проблемы - использовать один метод order_params и удалить order_charge и order_status, потому что в любом случае обновляется только один ресурс.И, как вы сказали, пользователь загружается только в одном случае при загрузке файла, поэтому вместо него используйте вспомогательный метод в контроллере , который будет отвечать за взимание платы с пользователя.

def charge_amount
    @amount = (@order.order_price).to_i * 100
    @amount_seller = (@order.order_price).to_i * 75
    if current_user.seller?
      charge = Stripe::Charge.create({
                        :amount      => @amount,
                        :description => 'Rails Stripe customer',
                        :currency    => 'usd',
                        :customer => @order.stripe_customer_token,
                        :destination => {
                          :amount => @amount_seller ,
                          :account => (@order.seller.stripe_token),
                        }
                      })
      @order.order_status = "charged"
    end
end

А внутри вашего метода обновления просто обновите заказ и взимайте плату с пользователя при необходимостиЭто будет что-то вроде

def update
  respond_to do |format|
    if user_signed_in? #this could be moved to a `before_action` that authenticates the user
      if @order.update(order_status)
        if order_params[:video].present?
          charge = charge_amount
        end
        format.html { redirect_to ([@user, @order]), notice: 'Order was successfully order_status.' }
        format.json { render :show, status: :ok, location: @order }
      else
        format.html { render :edit }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end
end

При таком подходе код будет уменьшаться в размере и отделять логику, и его будет легче отлаживать.Я надеюсь, что это ответит на ваш вопрос или, по крайней мере, даст вам некоторые рекомендации.

update Если вы хотите отдельные действия, просто создайте три метода в вашем контроллере и в зависимости от типа параметров вызовите соответствующий методв вашем update действии.

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