'Where is the login_url defined? NameError: undefined local variable or method `login_url'
I am reading Agile Development with Rails 5 by Sam Ruby. https://pragprog.com/book/rails51/agile-web-development-with-rails-5-1
In Chapter 14 Task I:Logging in after I use rails test, the console gives the following errors
Error:
ProductTest#test_image_url:
NameError: undefined local variable or method `login_url' for #<ProductTest:0x00000000062aadb8>
Did you mean? login_as
test/test_helper.rb:10:in `login_as'
test/test_helper.rb:16:in `setup'
bin/rails test test/models/product_test.rb:38
E
Error:
ProductTest#test_product_price_must_be_positive:
NameError: undefined local variable or method `login_url' for #<ProductTest:0x0000000005b9b068>
Did you mean? login_as
test/test_helper.rb:10:in `login_as'
test/test_helper.rb:16:in `setup'
bin/rails test test/models/product_test.rb:15
E
Error:
ProductTest#test_product_is_not_valid_without_a_unique_title:
NameError: undefined local variable or method `login_url' for #<ProductTest:0x0000000008349948>
Did you mean? login_as
test/test_helper.rb:10:in `login_as'
test/test_helper.rb:16:in `setup'
bin/rails test test/models/product_test.rb:50
E
Error:
ProductTest#test_product_attributes_must_not_be_empty:
NameError: undefined local variable or method `login_url' for #<ProductTest:0x0000000007ff8c08>
Did you mean? login_as
test/test_helper.rb:10:in `login_as'
test/test_helper.rb:16:in `setup'
bin/rails test test/models/product_test.rb:6
.......E
Error:
UserStoriesTest#test_buying_a_product:
ActionView::Template::Error: undefined method `each' for nil:NilClass
app/views/store/index.html.erb:7:in `block in _app_views_store_index_html_erb__32180898452112054_53581700'
app/views/store/index.html.erb:6:in `_app_views_store_index_html_erb__32180898452112054_53581700'
test/integration/user_stories_test.rb:16:in `block in <class:UserStoriesTest>'
I tried searching for a solution online but could'nt find one. Agile Web Development Rails 5 test failures This is a similar problem with same error but I didn' understand the solution
My test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
def login_as(user)
post login_url, params: { name: user.name, password: 'secret' }
end
def logout
delete logout_url
end
def setup
login_as users(:one)
end
# Add more helper methods to be used by all tests here...
end
My config/routes.rb
Rails.application.routes.draw do
get 'admin' => 'admin#index'
controller :sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
resources :users
resources :orders
resources :line_items
resources :carts
root 'store#index', as: 'store_index'
resources :products do
get :who_bought, on: :member
end
end
Solution 1:[1]
In the tutorial, login_url is intended to be a URL helper defined by Rails, based on this line in routes.rb:
controller :sessions do
get 'login' => :new
end
All routes have a helper generated to reach them, and you can grep this using rails routes -G login. In your case, this will give a line something like:
login GET /login(.:format) sessions#new
What this shows is 1) the route name and HTML method, 2) the path and 3) the controller#action handling it.
In the above example, login_url would work, as the route name can be suffixed by either _url or _path due to the auto-generated helper.
However, it's likely you won't see exactly this as you're having problems. You might see, for example:
sessions GET /login(.:format) sessions#new
This means you have two options:
Use sessions_url in place of login_url.
Or, and likely the correct solution, name your route in routes.rb using as:
controller :sessions do
get 'login' => :new, as: 'login'
end
Do that, and your route should be renamed to login and therefore login_url be made available.
Let me know how you get on or if you've any questions :)
Solution 2:[2]
@rohitjoshi Please declare the ActionDispatch class, as follows:
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
class ActiveSupport::TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end
class ActionDispatch::IntegrationTest
def login_as(user)
post login_url, params: { name: user.name, password: 'secret' }
end
def logout
delete logout_url
end
def setup
login_as users(:one)
end
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | SRack |
| Solution 2 | Colin He |
