I'm trying to fix the default tests for a polymorphic nested resource and running into lots of issues. I'm betting there is a simple solution that this newbie just hasn't wrapped his head around yet. Any help would be greatly appreciated as always.
My Models:
class Member < ActiveRecord::Base
has_many :names, as: :person
has_many :dependents
attr_accessible :active, :deleted
end
class Name < ActiveRecord::Base
belongs_to :person, polymorphic: true
attr_accessible :dob, :dod, :first, :gender, :last, :mi, :prefix, :relation, :suffix
end
routes.rb:
resources :dependents do
resources :names
end
resources :members do
resources :names
end
Example Test:
require 'test_helper'
class NamesControllerTest < ActionController::TestCase
setup do
#name = names(:one)
#person = members(:one)
end
test "should get edit" do
get :edit, id: #name
assert_response :success
end
end
Error I'm receiving:
3) Error:
test_should_get_edit(NamesControllerTest):
ActionController::RoutingError: No route matches {:id=>"980190962", :person_id=>"980190962", :controller=>"names", :action=>"edit"}
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:544:in raise_routing_error'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:540:inrescue in generate'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:532:in generate'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:573:ingenerate'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:569:in generate_extras'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb:565:inextra_keys'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_controller/test_case.rb:153:in assign_parameters'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_controller/test_case.rb:465:inprocess'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_controller/test_case.rb:49:in process'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/actionpack-3.2.13/lib/action_controller/test_case.rb:392:inget'
/Users/mkenney/hraccess/test/functional/names_controller_test.rb:43:in `block in '
If I add back in the non-nested route to names these errors run. How do I tell the test that it is a nested resource and does this have anything to do with the polymorphic relationship, or is that just noise that is throwing me off?
Thanks in advance for any help you can offer this newbie!
Mark
I needed to add the member_id to get the proper route I believe:
test "should get edit" do
get :edit, member_id: #person, id: #name
assert_response :success
end
Related
I'm getting an error when trying to test a Rails Controller with RSpec. It's a double nested route and I'm trying to figure out the right syntax but hadn't had many luck yet.
The error that I'm getting is
Failure/Error: get :index, {category_id: category.to_param, id: system.to_param}
ActionController::UrlGenerationError:
No route matches {:action=>"index", :category_id=>"220", :controller=>"reviews", :id=>"166"}
# ./spec/controllers/reviews_controller_spec.rb:11:in `block (3 levels) in <top (required)>'
I've made the same test for the system controller which works fine. The webpage works fine as well. No errors with that (just this error with testing).
Here is what the RSpec test look like:
require 'rails_helper'
RSpec.describe ReviewsController, type: :controller do
let (:category) { create(:category) }
let (:system) { create(:system) }
let (:reviews) { create_list(:review, 3, category: category, system: system) }
describe "GET index" do
it "assigs all reviews to an instance var called #reviews" do
get :index, {category_id: category.to_param, id: system.to_param}
expect(assigns(:reviews)).to eq reviews
end
it "assigns all the reviews to an var called #system" do
get :index, system_id: system.to_param
expect(assigns(:system)).to eq system
end
end
describe "system scope" do
before { create(:review) }
it "only assigns reviews index in the current system" do
get :index, {category_id: category.to_param, id: system.to_param}
expect(assigns(:reviews)).to eq reviews
end
end
end
This is the Controller that it's testing:
class ReviewsController < ApplicationController
def index
#system = System.find(params[:system_id])
#reviews = #system.reviews
respond_to do |format|
format.html
format.json { render json: { system: #system, reviews: #reviews } }
end
end
def show
#system = System.find(params[:system_id])
#review = #system.reviews
end
end
And these are the routes:
Rails.application.routes.draw do
root "categories#index"
resources :categories do
resources :systems do
resources :reviews
end
end
end
Here are the models:
Category Model
class Category < ActiveRecord::Base
validates_presence_of :name
has_many :systems
end
System Model
class System < ActiveRecord::Base
belongs_to :category
has_many :reviews
validates_presence_of :name, :category
end
Review Model
class Review < ActiveRecord::Base
belongs_to :system
validates_presence_of :content, :system
end
ActionController::UrlGenerationError: No route matches
{:action=>"index", :category_id=>"220", :controller=>"reviews",
:id=>"166"}
According to your routes, that particular index route expects category_id and system_id as keys. You need to change :id to :system_id. The below should work.
it "only assigns reviews index in the current system" do
get :index, {category_id: category.to_param, system_id: system.to_param}
expect(assigns(:reviews)).to eq reviews
end
Update
NoMethodError: undefined method `category=' for
Review:0x005578a9e87188
There is no association between a review and a category. Edit your models to set the association accordingly.
#category.rb
class Category < ActiveRecord::Base
validates_presence_of :name
has_many :systems
has_many :reviews
end
#review.rb
class Review < ActiveRecord::Base
belongs_to :system
belongs_to :category
validates_presence_of :content, :system
end
I'm currently working with a small team on an open source Rails 4 chess application, and I'm trying to test out various possible piece moves in RSpec (including special cases such as en passant and castling). A senior web developer suggested that I use a separate table to keep track of the moves taken in each game of chess. After taking him up on his suggestion, I'm having trouble testing out valid moves, as shown in the error message below. I suspect that it might be a problem with my associations, but the teammates that I was able to talk to about this were unsure about the cause.
Any help would be greatly appreciated.
Error message:
Failures:
1) PiecesController Action: pieces#update should create a move when a move is valid
Failure/Error: #current_game ||= current_piece.game
NoMethodError:
undefined method `game' for nil:NilClass
# ./app/controllers/pieces_controller.rb:36:in `current_game'
# ./app/controllers/pieces_controller.rb:40:in `require_authorized_for_current_game'
# ./spec/controllers/pieces_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
The test:
RSpec.describe PiecesController, type: :controller do
describe "Action: pieces#update" do
it "should create a move when a move is valid" do
user_sign_in
game = FactoryGirl.create(:game)
# Test a white pawn's movement on its first turn:
piece = FactoryGirl.create(:piece)
move = FactoryGirl.create(:move)
# Why can't I call game.id below?
patch :update, :id => game.id, :pieces => { }
piece_params = { :x_position => piece.x_position, :y_position => piece.y_position, :type => "Pawn" }
if piece.valid_move?(piece_params)
...
end
end
end
private
def user_sign_in
user = FactoryGirl.create(:user)
sign_in user
end
end
Associations:
class Game < ActiveRecord::Base
has_many :pieces
has_many :moves, through: :pieces
belongs_to :white_player, class_name: 'User', foreign_key: :white_player_id
belongs_to :black_player, class_name: 'User', foreign_key: :black_player_id
...
end
class Piece < ActiveRecord::Base
belongs_to :game
has_many :moves
def valid_move?(params)
...
end
...
end
class Move < ActiveRecord::Base
belongs_to :piece
end
Factories:
FactoryGirl.define do
factory :user do
...
end
factory :game do
association :white_player, factory: :user
association :black_player, factory: :user
turn 1
end
factory :piece do
association :game
...
end
# Set up an initially empty move, then adjust the values after checking that a piece can be moved:
factory :move do
association :piece
...
end
end
The controller:
class PiecesController < ApplicationController
before_action :authenticate_user!
before_action :require_authorized_for_current_game, only: [:update]
before_action :require_authorized_for_current_piece, only: [:update]
def update
...
end
...
private
def current_piece
#current_piece ||= Piece.find_by_id(params[:id])
end
...
def piece_params
params.require(:piece).permit(:x_position, :y_position, :type, :captured)
end
def current_game
#current_game ||= current_piece.game
end
def require_authorized_for_current_game
if current_game.white_player != current_user && current_game.black_player != current_user
render text: 'Unauthorized', status: :unauthorized
end
end
end
I am new to rails and I have a task asking me to let a page admin to send invitations for regular users to be admins with him I implemented the part to reply to the invitations but I am stuck in an error and please tell me if I am on the right way here is my code for the invitation method
def invite
inviteUser = {"user_id" => current_user.id,"magazine_id" => params[:id]}
CollaborationInvitation.create(inviteUser)
#magazine = Magazine.find(params[:id])
redirect_to :back
end
Here is my model for the invitation:
class CollaborationInvitation < ActiveRecord::Base
belongs_to :user
belongs_to :magazine
end
Model for page:
class Magazine < ActiveRecord::Base
mount_uploader :image, ImgUploader
has_many :articles
acts_as_followable
has_and_belongs_to_many :users
errors[:image] << 'should be less than 5MB' if image.size > 5.megabytes
validates :name, presence: true
validates :image, presence: true
validate :image_size
end`
And the routes:
routes`member do
put 'follow' => 'magazines#follow'
put 'unfollow' => 'magazines#unfollow'
put 'invite' => 'magazines#invite'
end
error : No route matches [GET] "/magazines/3/invite"
and when I changed the route from put to get
I get this error: unknown attribute 'user_id' for CollaborationInvitation.
It looks like you just need to setup the routes properly as resources. Remove the routes listed above and define these instead:
resources :magazines do
member do
put :follow
put :unfollow
put :invite
end
end
I've got a problem with my vote methods for comments. Im a begginer at RoR and waiting for your suggestions.
The error I get is:
ActionController::RoutingError at /posts/51f7d1279fefa5405a000003 No
route matches {:controller=>"comments", :action=>"vote(1)",
:class=>"post__button--edit"}
My code:
comment.rb
class Comment
include Mongoid::Document
field :name, type: String
field :email, type: String
field :body, type: String
field :up_vote, type: Integer, default: "0"
field :down_vote, type: Integer, default: "0"
belongs_to :post
validates_presence_of :name, :email, :body
def self.add_up_vote
self.increment(:up_vote, 1)
end
def self.add_down_vote
self.decrement(:down_vote, 1)
end
end
comment_controller.rb
.
.
.
def vote(a)
#comment = Comment.find(params[:comment_id])
#post = Post.find(params[:post_id])
if a == 1
comment.add_up_vote
redirect_to #post
elsif a == -1
comment.add_down_vote
redirect_to #post
else
redirect_to #post
end
end
routes.rb
Easyblog::Application.routes.draw do
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users
resources :posts do
resources :comments
member do
post :mark_archived
end
end
end
Im waiting for your help :)
What is a here? I guess it's vote direction
You have to remove argument a from vote action and pass direction via params for link path.
Fox example:
vote_comment_path(#comment.id, dir: 1) # or dir: -1
More than that there is no route for vote action. You can describe it like so:
resources :comments do
put :vote, as: :member
end
upd I would recommend you to read following guide http://guides.rubyonrails.org/routing.html
action in your path is not valid. You link should looks like
= link_to 'Yes', vote_comment_path(comment, dir: 1), method: :put
vote_comment_path can be different you could check it by rake routes command:
$ rake routes
Try changing like this
Easyblog::Application.routes.draw do
resources :posts do
resources :comments do
match :vote
end
member do
post :mark_archived
end
end
end
you could try something like this in youre routes
resources :posts do
resources :comments do
member do
post 'vote'
end
end
member do
post :mark_archived
end
No need to build your own voting system. Take a look at the voteable_mongo gem
I've got two models:
class Solution < ActiveRecord::Base
belongs_to :user
validates_attachment_presence :software
validates_presence_of :price, :language, :title
validates_uniqueness_of :software_file_name, :scope => :user_id
has_attached_file :software
end
class User < ActiveRecord::Base
acts_as_authentic
validates_presence_of :first_name, :last_name, :primary_phone_number
validates_uniqueness_of :primary_phone_number
has_many :solutions
end
with my routes looking like this:
map.resources :user, :has_many => :solutions
Now I'm trying to test my solutions controllers with the following RSpec test:
describe SolutionsController do
before(:each) do
#user = Factory.build(:user)
#solution = Factory.build(:solution, :user => #user)
end
describe "GET index" do
it "should find all of the solutions owned by a user" do
Solution.should_receive(:find_by_user_id).with(#user.id).and_return(#solutions)
get :index, :id => #user.id
end
end
end
However, this gets me the following error:
ActionController::RoutingError in 'SolutionsController GET index should find all of the solutions owned by a user'
No route matches {:id=>nil, :controller=>"solutions", :action=>"index"}
Can anybody point me to how I can test this, since the index should always be called within the scope of a particular user?
Factory#build builds an instance of the class, but doesn't save it, so it doesn't have an id yet.
So, #user.id is nil because #user has not been saved.
Because #user.id is nil, your route isn't activated.
try using Factory#create instead.
before(:each) do
#user = Factory.create(:user)
#solution = Factory.create(:solution, :user => #user)
end
Looks like your other problem is on this line:
get :index, :id => #user.id
You're trying to make a request to the index method, but you've provided the wrong variable name. When testing SolutionsController id implies a solution id, you need to supply the user id. This should work, or at least move you forward:
get :index, :user_id => #user.id