如何将after_sign_up_path_for重定向到另一个控制器的创建操作?



所以我有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.

你不需要super(resource).

在我的理解中,您想使用post方法重定向到orders_path(cart_id:@cart(。太奇怪了。after_sign_up_path_for应返回一个通过get方法访问的some_path。

您可以尝试另一种方式,从另一个控制器执行另一个操作。我认为这对您有所帮助。

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

你试过这个吗?

您遇到的问题是您的代码返回的是方法的原始值,而不是新路径:

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方法之前,应检查是否已在控制器中设置它。

您可以使用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 请求。在添加GET /posts/create路由之前,请记住 GET 不应用于非幂等操作。这意味着 GET 请求不应创建或更改任何资源。

如果您违反此规则,您的用户在点击后退按钮时可能会度过非常糟糕的一天。

不,您不想存储和重复发布操作。让用户提交表单 - 保存记录,然后重定向。如果需要,在记录中添加一个标志,以将其标记为"未确定"。将用户重定向回edit操作,然后通过执行 PUT 或 PATCH 请求(更新(来"完成订单"。

相关内容

  • 没有找到相关文章

最新更新