undefined method `protect_against_forgery?' fo

2020-04-05 07:04发布

问题:

I have the following code in my routes.rb file .

resources :users  do
  member do
    get :following,:followers
  end
  collection do
    put :activate_email
  end
 end

And I have a user email activation link like this :

<%= link_to "Activate",activate_email_users_url(email_token: @user.email_token),method: :put  %>

When I click on the activate link , this is the url that is generated

 http://localhost:3000/users/activate_email?email_token=WWNvMN-r_lXgovrQiDlSSQ

Update: Ok, So I think I kno what the problem is . When I look at the html source of the activation email in my gmail which contains the link_to , there is no

data-method='put'
. So that seems to be the problem . It is always sending a default GET request instead of PUT. This is my user_mailer/registration_confirmation.html.erb file

  <%= javascript_include_tag "application" %>
</head>

Please click on the following link to activate your email <%= link_to "Activate",activate_email_users_url(email_token: @user.email_token), method: :put %>

This gives the following error :

undefined method `protect_against_forgery?' for #

So , the code <%= javascript_include_tag "application" %>

is causing this error. Is there any way around this ?

回答1:

Sorry, I do not know your purpose, but apparently you have a purpose to activate user. Try this, if this solution not work, please tell me your action (activate_email) on controller!

see on rake routes output :

activate_email_users PUT /users/activate_email(.:format) users#activate_email user GET /users/:id(.:format) users#show

when your generate

http://localhost:3000/users/activate_email?email_token=WWNvMN-r_lXgovrQiDlSSQ

Your problem was activate_email considered to be :id

users/activate_email => users/:id

And solution for your problem :

Try removing the method from the link. Its better specifying the method in your routes file. How about replacing match by put in routes as :

resources :users  do
  member do
    get :following,:followers
  end
end
put "/users/activate_email/:email_token" => "users#activate_email", :as => "activate"

and on view

<%= link_to "Activate", activate_path(:email_token => @user.email_token)  %>

I have not tested this, but I guess this will suffice.

UPDATE

for Question : undefined method `protect_against_forgery?'

Add this to a helper that only your mailer template uses:

 def protect_against_forgery?
      false
 end

NOTE : If You have new question, please create new "Ask Question" and aprrove answer is usefull for this question



回答2:

If you're trying to activate a single user account you probably don't want to be specifying your route on the collection (which you would use for actions that operate on multiple users).

Here's some (untested) code that should point you in the right direction:

controller :users do
    put '/activate/:email_token', :to => :activate,  :as => 'activate_email'
end

Which should route a PUT to /activate/xxxx to the UsersController#activate action with a params[:email_token] set as xxxx. It should also give you a #activate_email_url route which you can pass the activation token (you can check what routes your app provides by running rake routes on the command line).



回答3:

Google redirected me to this question even-though mine was related to rendering a template into a string and not just in the browser. My solution for the template problem was something along these lines:

  action_controller = ActionController::Base.new()

  action_controller.class_eval do
    def protect_against_forgery?
      false
    end
  end

  file_string = action_controller.render_to_string('/some_template/template_file',locals: { local_variable: 1 }