Как перенаправить after_sign_up_path_for на действие создания другого контроллера? - PullRequest
0 голосов
/ 22 января 2020

Итак, у меня есть OrdersController#Create, и я бы хотел, чтобы пользователь был перенаправлен сразу после регистрации (чтобы он мог выполнять некоторые действия после регистрации).

До того, как я реализовал регистрационную часть этого рабочий процесс, вот как выглядел link_to для этого ресурса:

<%= link_to 'Submit to Scheduling', orders_path(cart_id: @cart), method: :post, data: { confirm: "Are you sure?" }, class: "primary button btn" %>

В общем, я хотел бы достичь вышеуказанной функциональности (включая передачу объекта @cart в качестве параметра), но автоматически из Devise::RegistrationsController#Create.

я использую Devise, и поэтому я создал /users/registrations_controller.rb, и в этом контроллере я делаю это:

  def after_sign_up_path_for(resource)
    orders_path(cart_id: @cart)
    super(resource)
  end

Когда я сделал выше , он успешно создал пользователя и перенаправил меня на Orders#Index, что не то, что я хочу, см. журналы ниже:

 User Create (1.3ms)  INSERT INTO "users" ("email", "encrypted_password", "first_name", "last_name", "created_at", "updated_at", "company_name", "company_title", "phone") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"  [["email", "abc3@test.com"], ["encrypted_password", "$2a$11$ZC2X2vCXd5JwVO"], ["first_name", "Test"], ["last_name", "User 3"], ["created_at", "2020-01-22 06:16:11.358863"], ["updated_at", "2020-01-22 06:16:11.358863"], ["company_name", "Acme Inc"], ["company_title", "CFO"], ["phone", "9876543210"]]
  ↳ app/controllers/users/registrations_controller.rb:14:in `create'
   (0.6ms)  COMMIT
  ↳ app/controllers/users/registrations_controller.rb:14:in `create'
Redirected to http://localhost:3000/orders
Completed 302 Found in 162ms (ActiveRecord: 5.3ms | Allocations: 6383)


Started GET "/orders" for ::1 at 2020-01-22 01:16:11 -0500
Processing by OrdersController#index as HTML

Я даже попробовал orders_path(cart_id: @cart, method: :post), и это не сработало.

Как мне добиться того, что я пытаюсь сделать?

Редактировать 1

Итак, я обнаружил url_for, и это ПОЧТИ меня доставляет туда, но это не так т вполне работает.

Вот что у меня есть:

url_for(controller: '/orders', action: 'create', method: :post, cart_id: @cart.id, only_path: true)

Вот что происходит:

↳ app/controllers/users/registrations_controller.rb:14:in `create'
  User Create (5.5ms)  INSERT INTO "users" ("email", "encrypted_password", "first_name", "last_name", "created_at", "updated_at", "company_name", "company_title", "phone") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"  [["email", "abc2@test.com"], ["encrypted_password", "$2a$ezj6"], ["first_name", "Test"], ["last_name", "User 2"], ["created_at", "2020-01-22 07:26:09.589560"], ["updated_at", "2020-01-22 07:26:09.589560"], ["company_name", "Acme Inc"], ["company_title", "CEO"], ["phone", "9876543210"]]
  ↳ app/controllers/users/registrations_controller.rb:14:in `create'
   (1.1ms)  COMMIT
  ↳ app/controllers/users/registrations_controller.rb:14:in `create'
/.rvm/gems/ruby-2.7.0@myapp/gems/devise-4.7.1/app/controllers/devise_controller.rb:187: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
.rvm/gems/ruby-2.7.0@myapp/gems/i18n-1.8.1/lib/i18n.rb:195: warning: The called method `t' is defined here
Redirected to http://localhost:3000/orders?cart_id=10&method=post
Completed 302 Found in 307ms (ActiveRecord: 13.2ms | Allocations: 8600)


Started GET "/orders?cart_id=10&method=post" for ::1 at 2020-01-22 02:26:09 -0500
Processing by OrdersController#index as HTML

Так что все равно не работает. Он все еще отправляет меня на OrdersController#Index.

Ответы [ 4 ]

1 голос
/ 22 января 2020

Вам не нужно super(resource).

В моем понимании, вы хотите перенаправить на orders_path (cart_id: @cart) с помощью метода post. Это так странно. after_sign_up_path_for должен возвращать some_path, доступ к которому осуществляется методом get.

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

0 голосов
/ 22 января 2020

Вы можете использовать Devise::Controllers::StoreLocation#store_location_for, который используется для перенаправления назад после входа в систему.

store_location_for(current_user, new_order_path(cart_id: @cart))

Здесь хранится местоположение сеанса. Вы можете получить значение с помощью stored_location_for.

def after_sign_up_path_for(resource)
  stored_location_for(resource) || super
end

Однако вы не можете / не должны перенаправлять на действие создания. Создать отвечает на запросы POST. Перенаправления всегда являются запросами GET. Прежде чем go добавить маршрут GET /posts/create, помните, что GET не следует использовать для неидемпотентных действий. Это означает, что запрос GET не должен создавать или изменять какие-либо ресурсы.

Если вы нарушите это правило, у ваших пользователей может быть действительно плохой день, когда они нажмут кнопку "Назад".

И нет, вы не хотите сохранять и повторять действия после публикации. Пусть пользователь отправит форму - сохраните запись и затем перенаправьте. При необходимости добавьте флаг к записи, чтобы пометить его как «не законченный». Перенаправьте пользователя обратно к действию edit, а затем "завершите sh порядок", выполнив запрос PUT или PATCH (обновление).

0 голосов
/ 22 января 2020

Проблема в том, что ваш код возвращает исходное значение метода, а не новый путь:

def after_sign_up_path_for(resource)
  orders_path(cart_id: @cart)
  super(resource)
end

Возвращает переопределенный метод, поскольку вы вызываете super(resource) в качестве конечного выражения. в методе, и его результат возвращается указанным вами методом.

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

def after_sign_up_path_for(resource)
  res = orders_path(cart_id: @cart)
  super(resource)
  res
end

Вы должны проверить метод, вызываемый super, хотя, возможно, вы можете просто полностью удалить его.

Не видя остальной части вашего кода, невозможно сказать, имеет ли @cart значение или оно просто nil. Вы должны проверить, что он был установлен в контроллере до вызова метода after_sign_up_path_for.

0 голосов
/ 22 января 2020
  request.params.merge!(cart_id: @cart.id)
  controller_you_want = OrdersController.new
  controller_you_want.request = request
  controller_you_want.response = response
  controller_you_want.create

Вы пробовали это?

...