Why does devise me redirect me to /users instead o

2019-09-09 22:12发布

问题:

The problem is like this:

If I use the default registration controller I get redirected:

  • /users/edit to root when user update succeeds
  • /users/edit to /users when update fails

Because the default controller update action looks like this:

if resource_updated
  sign_in resource_name, resource, bypass: true
  respond_with resource, location: after_update_path_for(resource)
else
  clean_up_passwords resource
  respond_with resource
end

after_update_path_for is set by default to root

If update fails I get the devise error messages and hasError div wrappers for the fields with error

In my registrations controller in the edit action I attribute values to a variable @myvar={2, 3}

This variable is used in the registrations_edit view

Whenever user update fails I get error no method .each for nil for my @myvar

How should I declare my view variables such that they are accessible even when update form fails?!

I have tried:

Forcing the controller to redirect to edit view no matter what:

if resource_updated
  sign_in resource_name, resource, bypass: true
  redirect_to edit_user_registration_path
else
  clean_up_passwords resource
  redirect_to edit_user_registration_path
end

This created problems because devise validations do not work anymore

Edit-------

My registrations edit:

def edit
  @images = Dir.glob("public/assets/images/users/#{current_user.id}/med/*")
end

My view:

<% img_paths = Array.new %>
  <% @images.each do |image| %>
  <%img_paths.push([
    '',
    "/assets/images/users/#{current_user.id}/original/#{image.split('/').last}",
    {'data-img-src'=>"/assets/images/users/#{current_user.id}/med/#{image.split('/').last}"}
    ])%>
  <% end %>

Edit-----

Registration controller:

class Users::RegistrationsController < Devise::RegistrationsController

  def edit
    @images = Dir.glob("public/assets/images/users/#{current_user.id}/med/*")
  end

  def update
    if params[:image_file_path]
      ff = File.open("public/"+params[:image_file_path])
      resource.image = ff
      resource.save!
    end
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    resource_updated = resource.update_with_password(account_update_params)
    yield resource if block_given?
    if resource_updated
      if is_flashing_format?
        flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
          :update_needs_confirmation : :updated
        set_flash_message :notice, flash_key
      end
      sign_in resource_name, resource, bypass: true
      respond_with resource, location: after_update_path_for(resource)
    else
      clean_up_passwords resource
      respond_with resource
    end
  end


  private

  def sign_up_params
    params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :telephone, :image, :address, :birthday)
  end

  def account_update_params
    params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :telephone, :image, :image_file_path, :address, :birthday)
  end

  protected 

  def update_resource(resource, params)
    resource.update_without_password(params)
  end

  def after_update_path_for(resource)
    edit_user_registration_path
  end

end

回答1:

You can try this;-

def update
    if params[:image_file_path]
      ff = File.open("public/"+params[:image_file_path])
      resource.image = ff
      resource.save!
    end
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    resource_updated = resource.update_with_password(account_update_params)
    yield resource if block_given?
    if resource_updated
      if is_flashing_format?
        flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
          :update_needs_confirmation : :updated
        set_flash_message :notice, flash_key
      end
      sign_in resource_name, resource, bypass: true
      respond_with resource, location: after_update_path_for(resource)
    else
    @images = Dir.glob("public/assets/images/users/#{current_user.id}/med/*")

      clean_up_passwords resource

      respond_with resource
    end
  end


回答2:

If you get redirected, all the controller instance variables get dumped, so there's no way to get around that except saving the data you need in some place that's propagated through the redirect. One such place is in a flash message (if you need a string and use it just once).

Another option is to store that in the session and pick it up on the other side.

I could tell you more if you paste your registrations#edit action in the question.