Rails 4 Undefined Local Variable or Method for Download link - ruby-on-rails

I keep getting undefined local variable or method `orders_download_template_path' for #<#:0x0000376c505098>
with the following code. I have also tried download_template_path and #orders_download_template_path (this last one doesn't throw an error, but does nothing either).
Routes.rb:
resources :orders do
collection do
post :import
get :upload_page, as: 'upload_page'
get :search, as: 'search'
get :csv_report, as: 'csv_report'
get :overdue_csv_report, as: 'overdue_csv_report'
get :download_template, as: 'download_template'
end
end
orders_controller.rb:
def download_template
send_file Rails.root.join('public/upload_template.csv'),
type: 'application/csv',
x_senfile: true
end
view:
<%= link_to "Blank Upload Template", orders_download_template_path %>
The File has been Placed under /public

Based on the Rails routing guide, you have a syntax error.
http://guides.rubyonrails.org/routing.html#adding-collection-routes
This should fix it
download_template_orders_path

If you run rake routes on your console, you should see the following line (among others):
download_template_orders GET /orders/download_template(.:format) orders#do
as you can see, if you're setting this route on a COLLECTION, the path generate would be download_template_orders_path.
If you set it on a MEMBER, you would see this:
download_template_order GET /orders/:id/download_template(.:format) orders#
Answering your question, the correct path would be download_template_orders_path

Related

Undefined method in controller (Routing)

I'm new at rails and I'm currently working on an already existing application that handles butons like so:
<%= link_to 'Edit', edit_answer_path(ans) %>
That links to the file /answers/edit.html.erb but now I need to make a button that links to the file /answers/comment.html.erb how do I go about doing this?
I already tried with
<%= link_to 'Comment', comment_answer_path(ans) %>
but I get the error "Undefined method 'comment_answer_path'" even after adding this lines to answers_controller :
def comment
ans = Answer.find(params[:id])
end
You need to add a route to your config/routes.rb and then restart the server. Something like
resources :answers do
member do
get 'comment'
end
end
will create the comment_answer_path helper for you as well.
It depends on how you've set up the routes in routes.rb.
You can use rake routes to see the list of all paths and their alias.

routes as: path variable not working

I have the following route
resources :projects do
collection do
get 'svdbf', to: 'projects#new', as: 'otherstuff'
end
end
and I am trying to make this link work on the view
<%= link_to 'Other Stuff', otherstuff_url %>
But it's returning the following rails error:
undefined local variable or method `otherstuff_url'
What am I doing wrong?
Based on the rake routes output you posted, a working path would be
<%= link_to 'Other Stuff', otherstuff_projects_path %>
Please run rake routes from the console. That will give you a full list of routes as well as a list of helper functions available to you.
Also try otherstuff_path instead og otherstuff_url

NoMethodError with renamed nested resources (false route using link_to)

I've ran into a problem which causes link_to #resource to fail.
My view:
<% #test_thing = Bar.first #This one belongs to Foo.first %>
<%= link_to "test link", #test_thing %>
produces this error:
NoMethodError
undefined method `bar_path' for #<#<Class:0x007fd799bc1088>:0x007fd799bc8400>
Why does rails not produce the correct route using thing1_thing2_path?
routes.rb:
resources :foo, as: "thing1", path: "thing2" do
resources :bar, as: "thing2", path: "thing2"
end
In my models, "Foo" has_many :bars and "Bar" belongs_to :foo
rake routes:
thing1_thing2_index GET /thing2/:thing1_id/thing2(.:format) bar#index
POST /thing2/:thing1_id/thing2(.:format) bar#create
new_thing1_thing2 GET /thing2/:thing1_id/thing2/new(.:format) bar#new
edit_thing1_thing2 GET /thing2/:thing1_id/thing2/:id/edit(.:format) bar#edit
thing1_thing2 GET /thing2/:thing1_id/thing2/:id(.:format) bar#show
PATCH /thing2/:thing1_id/thing2/:id(.:format) bar#update
PUT /thing2/:thing1_id/thing2/:id(.:format) bar#update
DELETE /thing2/:thing1_id/thing2/:id(.:format) bar#destroy
thing1_index GET /thing2(.:format) foo#index
POST /thing2(.:format) foo#create
new_thing1 GET /thing2/new(.:format) foo#new
edit_thing1 GET /thing2/:id/edit(.:format) foo#edit
thing1 GET /thing2/:id(.:format) foo#show
PATCH /thing2/:id(.:format) foo#update
PUT /thing2/:id(.:format) foo#update
DELETE /thing2/:id(.:format) foo#destroy
root GET / bar#index
I'm using rails 4, but I had the same problem with rails 3.
I fell like it's a bug in rails, or am I doing something wrong?
Do not rename your routes. Remove the as: argument:
resources :foo, path: "thing2" do
resources :bar, path: "thing2"
end
Apart from that, you need to hand it both objects in order to produce the correct path:
<%= link_to "test link", [#test_thing.foo, #test_thing] %>
Have you tried passing the link explicitly? Something like:
<%= link_to "test link", bar_path(#test_thing) %>
...or whatever the correct *_path(variable) you should be using?
(Sorry, the test, and bar, and thing1, thing2 things got really confusing over here :P)

Rails routes.rb unexpected behaviour

Editing my Rails 4 app routes.rb file and I'm getting unexpected behaviour (unexpected form my point of view anyway).
I'm trying to create a link that updates a booking record. I have created an action in my BookingsController called WITHDRAW ready to handle the update process. I would like the link to pass the booking id and my code for the link is this:
<%= link_to "Withdraw this booking", bookings_withdraw_path(#booking), :confirm => "Are you sure you want to withdraw this booking?", :method => :patch %>
My problem arises when I try and setup the route for this link. If I add the following line to my routes file:
match 'bookings/withdraw/:bid' => 'bookings#withdraw', via: 'patch'
then when I run the rake command to check the routes it shows this:
bookings_withdrawn GET /bookings/withdrawn(.:format) bookings#withdrawn
PATCH /bookings/withdraw/:bid(.:format) bookings#withdraw
As you can see, the WITHDRAW path is part of the one above (WITHDRAWN is a different path by the way). If I remove the /:bid part from the path then it creates it's own path which is what I would expect.
Can someone explain why this is happening?
try this out
in you routes file pass a block to resources :bookings like this
resources :bookings do
member do
patch :withdraw
end
end
and remove this
match 'bookings/withdraw/:bid' => 'bookings#withdraw', via: 'patch'
As I've written in comment, you should add :as option to your route, i.e.:
match 'bookings/withdraw/:bid' => 'bookings#withdraw', via: 'patch', as: 'bookings_withdraw'
Named route probably wasn't autogenerated because of dynamic part :bid, AFAIK Rails aren't generating implicitly named routes in such cases, so you have to add them explicitly, but I still can't find it in an docs, maybe if somebody've got and can share so I'll update my answer.

undefined method `protect_against_forgery?' for #<#<Class:0x0

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 ?
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
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).
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 }

Resources