routes.rb
get 'students/name_starts_with/:letter', to: 'students#name_starts_with'
get 'students/with_last_name/:last', to: 'students#with_last_name'
students_controller.rb
def name_starts_with
#students = Student.all.select{|s| s.first_name.start_with?(params[:letter]}
render json: #students.to_json
end
def with_last_name
#students = Student.all.select{|s| s.last_name == params[:last]}
render json: #students.to_json
end
students_controller_spec.rb
context '#name_starts_with' do
let!(:first_student){Student.create(first_name: 'John', last_name: 'Doe'}
it "starts with #{first_student.first_name.split('').first}" do
get :name_starts_with
expect(response.status).to eq(200)
expect(first_student.first_name.split('').first).to be('J')
end
end
context '#with_last_name' do
let!(:first_student){Student.create(first_name: 'John', last_name: 'Doe'}
it "has last name #{first_student.last_name}" do
get :with_last_name
expect(response.status).to eq(200)
expect(first_student.last_name).to be('Doe')
end
end
I have seeded bunch of student names. As far as I know both of these should be get routes/get requests. I am getting same error for both:-
Failure/Error: get :name_starts_with
ActionController::UrlGenerationError:
No route matches {:action=>"name_starts_with", :controller=>"students"}
# ./spec/controllers/students_controller_spec.rb:45:in `block (3 levels) in <top (required)>'
Should they be POST routes instead. Am I missing something. Am I doing whole thing wrong. Can somebody please help me solve this issue please.
I think this is route matching error. parameter letter is missing in this call.
Replace
get :name_starts_with
with
get :name_starts_with, letter: first_student.first_name.split('').first
I think this will fix your error.
I know this sounds stupid, but is your StudentsController inheriting from ApplicationController? (ApplicationController inherits from ActionController::Base
...and I'm not sure if you need the #students.to_json if you already declared render :json in your controller. just put render json: #students
Related
I have a controller /dashboard/sites_controller.rb, within which I have an action attendance_summer_city_camp_integrativ
def attendance_summer_city_camp_integrativ
#site = Site.find(params[:site_id])
respond_to do |format|
format.xlsx
end
end
It returns an Excel, as you can see.
config/routes.rb
namespace :dashboard do
resources :sites do
get :attendance_summer_city_camp_integrativ
end
end
In my test file, when I do a get request on this address I get
No route matches {:action=>"/dashboard/sites/24/attendance_summer_city_camp_integrativ.xlsx", :controller=>"dashboard/sites"}
describe 'GET #attendance_summer_city_camp_integrativ' do
subject do
get dashboard_site_attendance_summer_city_camp_integrativ_path(site.id, format: :xlsx)
end
end
Failure/Error: get dashboard_site_attendance_summer_city_camp_integrativ_path(site.id, format: :xlsx)
ActionController::UrlGenerationError:
No route matches {:action=>"/dashboard/sites/24/attendance_summer_city_camp_integrativ.xlsx", :controller=>"dashboard/sites"}
When I go to this address manually in the browser it works fine.
Started GET "/dashboard/sites/6/attendance_summer_city_camp_integrativ.xlsx" for 127.0.0.1 at 2019-06-28 18:18:46 +0200
Processing by Dashboard::SitesController#attendance_summer_city_camp_integrativ as XLSX
What am I doing wrong?
Perhaps this:
describe 'GET #attendance_summer_city_camp_integrativ' do
subject do
get dashboard_site_attendance_summer_city_camp_integrativ_path(site.id, format: :xlsx)
end
end
Should be more like this:
describe 'GET #attendance_summer_city_camp_integrativ' do
subject do
get attendance_summer_city_camp_integrativ, {site_id: site.id, format: :xlsx}
end
end
(I guess, according to the docs, you may need to form your params differently for rails 5 v. pre-rails 5.)
You have an action called attendance_summer_city_camp_integrativ, but your test is trying to call the action /dashboard/sites/24/attendance_summer_city_camp_integrativ.xlsx. Which isn't an action, but a fully-formed url. So, maybe calling get dashboard_site_attendance_summer_city_camp_integrativ_path instead of get attendance_summer_city_camp_integrativ is the issue?
All. I am a beginner developer of Ruby on Rails. There is an error that I have been struggling and not been able to solve.
I am trying to see if an variable #chat_group declared in messages_controller.rb matches another variable declared in message_controller_spec.rb. I have not had any clue to solve this error because I am 100% positive that I am giving what I am supposed to give to as a parameter, which is chat_group_id as the route says.
Does anyone have any insight to solve this problem?
Or has anyone encountered a similar issue before?
If you does or has, could you please give a way of solving this problem?
Any advice would be appreciated! Thanks in advnace!
1) MessagesController#GET index when the user logs in Checking if the variable in index action matches
Failure/Error: get :index, params: index_params
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"messages", :params=>{:chat_group_id=>"522"}}
# ./spec/controllers/messages_controller_spec.rb:13:in `block (4 levels) in <top (required)>'
messages_controller_spec.rb
RSpec.describe MessagesController, type: :controller do
let(:chat_group) { create(:chat_group) }
let(:message) { create(:message) }
let(:index_params) { { chat_group_id: chat_group } }
describe '#GET index' do
context 'when the user logs in' do
login_user
it 'Checking if the variable in index action matches' do
get :index, params: index_params
expect(assigns(:chat_group)).to eq chat_group
end
end
end
end
Route.rb
chat_group_messages GET /chat_groups/:chat_group_id/messages(.:format) messages#index
POST /chat_groups/:chat_group_id/messages(.:format) messages#create
chat_groups GET /chat_groups(.:format) chat_groups#index
POST /chat_groups(.:format) chat_groups#create
new_chat_group GET /chat_groups/new(.:format) chat_groups#new
edit_chat_group GET /chat_groups/:id/edit(.:format) chat_groups#edit
chat_group PATCH /chat_groups/:id(.:format) chat_groups#update
PUT /chat_groups/:id(.:format) chat_groups#update
MessageController.rb
class MessagesController < ApplicationController
before_action :set_chat_group
def index
#chat_groups = current_user.chat_groups
#messages = #chat_group.messages
#message = Message.new
respond_to do |format|
format.html { render :index }
format.json { render json:
#chat_group.messages.includes(:user).map{|x| x.json_api} }
end
end
private
def set_chat_group
#chat_group = ChatGroup.find(params[:chat_group_id])
end
end
Update
I solved the error! I put the way of solving it in the comments below!
I am so sorry. I was looking at a documentation for Rails5 instead of Rails4.
It says that I should pass the chat_group_id by writing like below.
Rails4
before do
get :index, { chat_group_id: chat_group }
end
Not Like this
before do
get :index, params: { chat_group_id: chat_group }
end
This error made me realize how important it is to read the documentation...
For those who put comments and tried to do so, THANK YOU VERY MUCH!
try to change type: controller to type: request?
Also you can use, request type and specify path:
get chat_group_messages_path(chat_group.id), index_params
Cheers
I think You are doing everything right.
but this line : expect(assigns(:group)).to eq group
you expected assigns(:group) but i can't see any variable named group in your index action that you are testing.
also you are expecting that to equal group "eq group", but in your let blocks in the example above no variable named group exists.
So try to do expect(assigns(:chat_groups)).to eq chat_group
the assigns(:chat_groups) uses the same name of the instance variable inside your action, and the eq chat_group uses the name of the variable in the let block
I have a test that tries to view a subscription that doesn't exist. I run this test with a bunch of users from my fixtures. In the case of the user in the admin role when the app gets to the point of trying to render the response it has changed the action from :show to :edit and dropped the id param. Yet when I try and use byebug to trace the execution I never seem to be able to pinpoint when it happens.
my test is:
test "#{u.role} can not view subscriptions that don't exist" do
self.send('sign_in_' + u.role)
get :show, id:1234567890
assert_redirected_to root_path
assert_includes flash[:alert], "That subscription doesn't exist"
end
where u is a user loaded from my fixtures.
The error I get is:
SubscriptionsControllerTest#test_admin_can_not_view_subscriptions_that_don't_exist:
ActionView::Template::Error: No route matches {:action=>"edit", :controller=>"subscriptions", :id=>nil} missing required keys: [:id]
app/views/subscriptions/show.html.erb:13:in `_app_views_subscriptions_show_html_erb__1518678276755260966_70268849069860'
test/controllers/subscriptions_controller_test.rb:58:in `block (2 levels) in <class:SubscriptionsControllerTest>'
my controller looks like this:
class SubscriptionsController < ApplicationController
load_and_authorize_resource except: [:create,:new]
before_action :set_subscription
def show
end
def edit
end
...
private
def subscription_params
params.require(:subscription).permit(:email,:confirmed)
end
def set_subscription
#byebug if user_signed_in? && current_user.role == 'admin' && self.action_name == 'show'
begin
if (params.has_key? :id) && (controller_name == 'subscriptions')
#subscription = Subscription.find(params[:id])
elsif user_signed_in?
#subscription = current_user.subscription || Subscription.new(email: current_user.email)
else
#subscription = Subscription.new
end
rescue ActiveRecord::RecordNotFound
#subscription = Subscription.new
flash.alert = "That subscription doesn't exist"
end
end
end
load_and_authorize_resource comes from cancancan.
my routes related to this test are:
resources :subscriptions do
member do
get 'confirm'
end
end
I don't really know where to go from here, so any advice would be appreciated.
Take a look at the stack trace for this exception:
SubscriptionsControllerTest#test_admin_can_not_view_subscriptions_that_don't_exist:
ActionView::Template::Error: No route matches {:action=>"edit", :controller=>"subscriptions", :id=>nil} missing required keys: [:id]
app/views/subscriptions/show.html.erb:13:in `_app_views_subscriptions_show_html_erb__1518678276755260966_70268849069860'
test/controllers/subscriptions_controller_test.rb:58:in `block (2 levels) in <class:SubscriptionsControllerTest>'
app/views/subscriptions/show.html.erb, line 13. Are you calling link_to (or a similar helper method) with a nil ID, maybe?
Look at your error message. It says the id parameter is missing. It is possible you are giving it a nil value. Because of this the router can't route the request properly.
Also, the error is for an request to the edit action, but the code you are showing is calling the show action. Can you clean up the code examples and error messages shown and make them consistent?
Following is my rails controller:
class MyController < ApplicationController
def index
#client = (current_company.clients.size || 0) >= current_company.subscription.clients # it returns true or false
begin
#obj = Class.all
respond_to do |format|
format.html # index.html.erb
end
rescue
end
end
end
Following is my rspec code under (spec/controller):
require 'spec_helper'
describe MyController do
describe "GET index" do
it "populates an array of data" do
current_company = mock_model(CompaniesUser)
clients = mock_model(Client)
get :index
.
.
end
end
end
After execution it provide me following error:
Failures:
1) MyController GET index populates an array of clients
Failure/Error: get :index
Double "Company_1" received unexpected message :clients with (no args)
# ./app/controllers/my_controller.rb:20:in `index'
# ./spec/controllers/my_controller_spec.rb:28:in `block (3 levels) in <top (required)>'
So how to do this association about current_compnay.clients.size in rspec controller? It provides an error due to not getting value current_company.clients.size in controller's index method from spec.
Not sure if I understand your question correctly. Are you looking for something like this?
it "populates an array of data" do
controller.stub(:current_company) {
mock_model(CompaniesUser, clients: [mock_model(Client)])
}
get :index
# ...
Some changes after your comment:
let(:client) { mock_model(Client, :id => 1)}
let(:company) { mock_model(Company, :id => 1, :clients => [client])}
before { controller.stub(:current_company).and_return(company) }
it "populates an array of data" do
get :index
# ...
disclaimer: please do not swallow errors!
what is that begin rescue end part for? please go ahead and remove that. it hides any error that occurs when rendering a template!
what is that #obj = Class.all is that pseudo code? if you add pseudo code, make a note about that!
if you have such complex logic in your controller, it would be a good idea to move it into a method of that class. so (current_company.clients.size || 0) >= current_company.subscription.clients might be refactored to a call of current_company.has_not_enough_clients or whatever your business logic should name it.
then go ahead and stub that method or use a test-double for only that specific model.
Problem resolved as follow:
at start of controller spec:
let(:current_company) {mock_model(CompanyUser, :id => 1, clients: [mock_model(Client)])}
now you can access it as "current_company.clients.size" gives "1"
I found a lot of questions with same title but could not found the appropriate answer.
I am testing a controller
Player Controller
def create
player = Player.create(params[':player'])
if player.valid?
# if creation successful, log the player in:
player_session = PlayerSession.create(
player: player,
session_token: ActiveSupport::SecureRandom.urlsafe_base64
)
render json: {session_token: player_session.session_token}
else
render json: {error: "Player name already exists."}, status: :unprocessable_entity
end
end
Player Controller Test
test "create" do
post(:create,
{
'player' => {
'player_name' => "usman",
'password' => 123,
'email' => 'ranasaani#gmail.com'
}
}
)
assert_select response.body
end
while executing the test file the following errors display on console.
ActionController::RoutingError: No route matches {:player=>{"player_name"=>"usman", "password"=>123, "email"=>"ranasaani#gmail.com"}, :controller=>"pl
ayers", :action=>"create"}
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:424:in `raise_routing_error'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:406:in `generate'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:453:in `generate'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:449:in `generate_extras'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_dispatch/routing/route_set.rb:445:in `extra_keys'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_controller/test_case.rb:143:in `assign_parameters'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_controller/test_case.rb:402:in `process'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_controller/test_case.rb:47:in `process'
D:/jruby-1.7.1/lib/ruby/gems/shared/gems/actionpack-3.0.3/lib/action_controller/test_case.rb:355:in `post'
D:/Projects/lyricle/test/functional/players_controller_test.rb:5:in `test_create'
org/jruby/RubyBasicObject.java:1659:in `__send__'
why this error is here?
You have to define routes if you want anything to be able to access your controller.
So, in your config/routes.rb :
App::Application.routes.draw do
resources :your_resource_plural_name
end
The create action should be like this:
def create
#player = Player.new(params[:player])
#your code
end
also you need to add new action before create action:
def new
#player = Player.new
end
in routes.rb you should have resources :players
#player is an instance variable to make you able to call it in the view also.
See Rails Guide to create your first application.
Also check Rails for Zombies they are very good