问题
I have two route for my api v1 and v2 pointing to the same Devise model with the below routes:
scope :api do
namespace :v1 do
devise_for :users, :controllers => {:registrations => "devise/v1/users_registrations",
:sessions => "devise/v1/users_sessions",
:passwords => "devise/v1/users_passwords"}
end
end
scope :api do
namespace :v2 do
devise_for :users, :controllers => {:registrations => "devise/v2/users_registrations",
:sessions => "devise/v2/users_sessions",
:passwords => "devise/v2/users_passwords"}
end
end
My problem is when a request is sent to either one of these API's the Devise resource_name is either 'v1_user' or 'v2_user', but the parameters sent in have the values needed in params['user'].
I get this information from the Devise helpers.rb devise_parameter_sanitizer method. When Devise::ParameterSanitizer.new(resource_class, resource_name, params) params looks like below:
result = {ActionController::Parameters} ActionController::Parameters (4 elements)
'user' = {ActionController::Parameters} ActionController::Parameters (16 elements)
'email' = "test@kemsoft.co"
'password' = "qwertyuiop"
'first_name' = "test"
'last_name' = "testtest"
'ship_street_address' = "1 main st"
'ship_city' = "rome"
'ship_state' = "TX"
'ship_zip_code' = "12345"
'dealer_number' = "1234567890"
'business_name' = "ABC Pumps"
'bus_street_address' = "121 West Ave"
'bus_city' = "San Antonio"
'bus_state' = "NY"
'bus_zip_code' = "73412"
'distributor_id' = "1"
'additional_distributor_id' = "1"
'controller' = "devise/v1/users_registrations"
'action' = "create"
'format' = "json"
Not sure if this will be helpful information, but here is the devise_mapper:
result = {Devise::Mapping} #<Devise::Mapping:0x007fc7a2c8d950>
@class_name = "User"
@controllers = Hash (3 elements)
@failure_app = {Class} Devise::FailureApp
@format = nil
@klass = {Devise::Getter} #<Devise::Getter:0x007fc7a2c8d338>
@modules = Array (7 elements)
@path = "users"
@path_names = Hash (8 elements)
registration =>
new => new
edit => edit
sign_in => sign_in
sign_out => sign_out
password => password
sign_up => sign_up
cancel => cancel
@path_prefix = "/api/v1"
@router_name = nil
@routes = Array (3 elements)
[0] = {Symbol} session
[1] = {Symbol} password
[2] = {Symbol} registration
@scoped_path = "v1/users"
@sign_out_via = {Symbol} delete
@singular = {Symbol} v1_user
@strategies = Array (2 elements)
[0] = {Symbol} rememberable
[1] = {Symbol} database_authenticatable
@used_helpers = Array (3 elements)
[0] = {Symbol} session
[1] = {Symbol} password
[2] = {Symbol} registration
@used_routes = Array (3 elements)
[0] = {Symbol} session
[1] = {Symbol} password
[2] = {Symbol} registration
回答1:
I did end up coming up with a solution, but it's not one I like all that much. I'm still open to other suggestion so I'm not going to mark this as the accepted answer, but it atleast got the job done.
Basically in my devise controllers I added a before_filter that added the expected parameter to the request.parameters and local params. It's pretty simple, but feels really hacky. Of course I've unit tested the hell out of it incase changes break it in the future.
before_filter :sanitize_params
def sanitize_params
request.parameters[:v2_user] = params[:user] unless params[:user].nil?
params[:v2_user] = params[:user] unless params[:user].nil?
end
来源:https://stackoverflow.com/questions/34776486/issue-with-devise-resource-name-when-two-route-point-to-the-same-model