Following a tutorial for adding favorites to my existing project, whereby users can favorite property listings but can't get past the error below:
Routing error,uninitialized constant FavoriteRoomsController
favoriterooms_controller.rb
class FavoriteRoomsController < ApplicationController
before_action :set_room
def create
if Favorite.create(favorited: #room, user: current_user)
redirect_to #room, notice: 'Room has been favorited'
else
redirect_to #room, alert: 'Something went wrong...*sad panda*'
end
end
def destroy
Favorite.where(favorited_id: #room.id, user_id: current_user.id).first.destroy
redirect_to #room, notice: 'Room is no longer in favorites'
end
private
def set_room
#room = Room.find(params[:room_id] || params[:id])
end
end
room.rb
class Room < ActiveRecord::Base
belongs_to :user
has_many :photos
has_many :favorites
geocoded_by :address
after_validation :geocode, if: :address_changed?
validates :home_type, presence: true
validates :room_type, presence: true
validates :accommodate, presence: true
validates :bed_room, presence: true
validates :bath_room, presence: true
validates :listing_name, presence: true, length: {maximum: 50}
validates :summary, presence: true, length: {maximum: 500}
validates :address, presence: true
validates :lister_type, presence: true
validates :gender_type, presence: true
validates :occupation_type, presence: true
validates :move_in, presence: true
validates :term, presence: true
validates :term, presence: true
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
validates :fullname, presence: true, length: {maximum: 50}
has_many :rooms
has_many :favorites
has_many :favorite_rooms, through: :favorites, source: :favorited, source_type: 'Room'
def self.from_omniauth(auth)
user = User.where(email: auth.info.email).first
if user
return user
else
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.fullname = auth.info.name
user.provider = auth.provider
user.uid = auth.uid
user.email = auth.info.email
user.image = auth.info.image
user.password = Devise.friendly_token[0,20]
end
end
end
end
favorite.rb
class Favorite < ActiveRecord::Base
belongs_to :user
belongs_to :favorited, polymorphic: true
end
routes.rb
Rails.application.routes.draw do
root 'pages#home'
devise_for :users,
:path => '',
:path_names => {:sign_in => 'login', :sign_out => 'logout', :edit => 'profile'},
:controllers => {:omniauth_callbacks => 'omniauth_callbacks',
:registrations => 'registrations'
}
resources :users, only: [:show]
resources :rooms
resources :photos
resources :conversations, only: [:index, :create] do
resources :messages, only: [:index, :create]
end
resources :favorite_rooms, only: [:create, :destroy]
end
roomshow.html.erb
favorites button link code added in my roomsshow.html.erb
<%- unless current_user.favorite_rooms.exists?(id: #room.id) -%>
<%= link_to 'Add to favorites', favorite_rooms_path(room_id: #room), method: :post %>
<%- else -%>
<%= link_to 'Remove from favorites', favorite_room_path(#room), method: :delete %>
<%- end -%>
favorite_rooms_path POST /favorite_rooms(.:format) favorite_rooms#create
favorite_room_path DELETE /favorite_rooms/:id(.:format) favorite_rooms
Screenshot of error message with full trace
I've watched various tututorials and followed numerous suggestions but dont seem to be able to solve the issue by myself.
Routing error,uninitialized constant FavoriteRoomsController
Rails follow naming conventions very strictly and for a good reason. It expects the file names to be in a snake case. So you should change the file name favoriterooms_controller.rb to favorite_rooms_controller.rb
Related
I am having trouble making a test pass for my posts controller.
What is the proper way to test my create action inside the Posts controller with a polymorphic association?
I'm using Rails 4
Here's my code
Models:
class Topic < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_many :posts, as: :postable
has_many :posts, dependent: :destroy
validates :name, presence: true, length: {maximum: 50}
validates :description, presence: true, length: {maximum: 80}
validates :user_id, presence: true
is_impressionable
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :topic
belongs_to :category
belongs_to :postable, polymorphic: true
has_many :posts, as: :postable
validates :comment, presence: true
validates :user_id, presence: true
validates :topic_id, presence: true
validates :category_id, presence: true
default_scope { order(created_at: :asc) }
end
Post controller
class PostsController < ApplicationController
before_action :auth_user
before_action :set_post, only: [:destroy]
before_action :correct_user, only: [:destroy]
before_action :find_postable, only: [:create, :new]
def new
#post = #postable.posts.build
end
def create
#post = #postable.posts.build(post_params)
set_topic_id
set_category_id
#post.user_id = current_user.id
if #post.save
redirect_to topic_path(#post.topic.id)
else
redirect_to request.referer, notice: "Post unsuccessful!"
end
end
def destroy
#post.destroy
flash[:success] = 'Post deleted'
redirect_to request.referer || root_url
end
private
def set_post
#post = Post.find(params[:id])
end
def correct_user
#post = current_user.posts.find_by(id: params[:id])
redirect_to root_url if #post.nil?
end
def find_topic
#topic = Topic.find(params[:topic_id])
end
def find_postable
#postable = Post.find_by_id(params[:post_id]) if params[:post_id]
#postable = Topic.find_by_id(params[:topic_id]) if
params[:topic_id]
end
def post_params
params.require(:post).permit(:comment)
end
end
Post controller test:
require 'test_helper'
class PostsControllerTest < ActionController::TestCase
def setup
#topic = topics(:topicone)
#post = posts(:postone)
#posttwo = posts(:posttwo)
#category = categories(:categoryone)
#user = users(:user1)
end
test 'should create post when logged in' do
sign_in #user
assert_difference 'Post.count', 1 do
post :create, post: { user_id: #user.id, category_id:
#category.id, topic_id: #topic.id, comment: "First reply!",
postable_id: #post.id, postable_type: "Post" }
end
end
end
When I run the test above I get this error:
ERROR["test_should_create_post_when_logged_in", PostsControllerTest,
2016-12-04 14:23:25 -0500]
test_should_create_post_when_logged_in#PostsControllerTest
(1480879405.93s)
NoMethodError: NoMethodError: undefined method `posts' for nil:NilClass
app/controllers/posts_controller.rb:13:in `create'
test/controllers/posts_controller_test.rb:28:in `block (2
levels) in <class:PostsControllerTest>'
test/controllers/posts_controller_test.rb:25:in `block in
<class:PostsControllerTest>'
app/controllers/posts_controller.rb:13:in `create'
test/controllers/posts_controller_test.rb:28:in `block (2 levels)
in <class:PostsControllerTest>'
test/controllers/posts_controller_test.rb:25:in `block in
<class:PostsControllerTest>'
From my understanding, I believe it's telling me that it can't find whether the create action is posting to a post or to a topic.
The site works great in development and production. The problem is in this test.
How can I rewrite this test and make it so it recognizes to whom it's posting to?
I found a solution for this shortly after.
In this case, to successfully test if a post is created on a topic, make sure to provide the topic_id.
test 'should create post on a topic when logged in' do
sign_in #user
assert_difference 'Post.count', 1 do
post :create, topic_id: #topic, post: {
user_id: #user.id,
category_id: #category.id,
comment: 'First post on a topic!' }
end
end
Now to test if a post is created on another post, make sure to provide the post_id.
test 'should create post on another post when logged in' do
sign_in #user
assert_difference 'Post.count', 1 do
post :create, post_id: #post, post: {
user_id: #user.id,
category_id: #category.id,
comment: 'First post on a topic!' }
end
end
New to RoR, here couldn't find the solution I was looking for so I'm typing my problem here:
I have a web app where after the user is logged in they will be redirected to a dashboard that shows them their various information.
For now - as I'm getting the feel of RoR - the view of the dashboard was suppose to get a lot of information:
def index
#logged_user = Person.includes(:user, :addresses).find(session[:user_id])
end
but when I checked using #logged_user.inspect it only gave me this
#<Person (person model attributes here) >
I checked the log and it seems the User and Addresses were loaded
printscreen of my log http://prntscr.com/c40fee
but they aren't in the #logged_user variable... did I miss a step here? where did I go wrong?
EDIT:
here's the model of Person
class Person < ActiveRecord::Base
validates :first_name, :last_name, presence: true
has_one :user, :dependent => :destroy
has_one :medical_record
has_many :addresses, :dependent => :destroy
has_many :contacts,:dependent => :destroy
has_many :enrollments_as_student, :class_name => 'Enrollment', :foreign_key => :student_id, :dependent => :destroy
accepts_nested_attributes_for :addresses, allow_destroy: true
accepts_nested_attributes_for :contacts, allow_destroy: true
accepts_nested_attributes_for :medical_record, allow_destroy: true
end
model for User
class User < ActiveRecord::Base
validates :username, presence: true
validates :username, :password, format: {with: /\A[a-zA-Z0-9 ñÑ]+\Z/, message: "Special characters aren't allowed"}
validates :username, uniqueness: {message: "username is already taken"}
has_secure_password
belongs_to :person
end
model for Addresses
class Address < ActiveRecord::Base
validates :street, :barangay, :city, :province,
presence: {message: "Fill in all necessary fields"}
validates :zipcode,
numericality: {message: "Zipcodes should only contain numbers"},
length: {minimum: 4, maximum: 4, message: "Invalid zipcode length"}
belongs_to :person
end
also snippet for the login
def login
#user = User.find_by_username(params[:receptions][:username])
if #user && #user.authenticate(params[:receptions][:password])
session[:user_id] = #user.person_id
flash[:notice] = "You have succfully logged in"
redirect_to '/dashboards'
else
flash[:notice] = "Invalid username or password"
redirect_to '/login'
end
I have manually specified the relationships in the models (haven't found a way how to automatically generate them from a ERD model or an existing database) and than tried to generate a migration containing the FKs using the immigrant gem. I am getting:
rails generate immigration AddKeys
lib/active_support/dependencies.rb:478:in `load_missing_constant': Circular dependency detected while autoloading constant Assignment (RuntimeError)
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451#railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:180:in `const_missing'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451#railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:512:in `load_missing_constant'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451#railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:180:in `const_missing'
Here is the code for the models:
class Account < ActiveRecord::Base
include Person
include Contact
has_many :coworkers, :class_name => 'Coworker'
has_many :customers, :class_name => 'Customer'
has_many :locations, :class_name => 'Location'
has_many :appointment_types, :class_name => 'AppointmentType'
before_create :create_remember_token
has_secure_password
validates :password, length: { minimum: 6 }
validates :rem_notice_hrs, presence: true
validates :rem_notice_hrs, numericality: true
validates :rem_text, presence: true
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX }
after_initialize :init
def Account.new_remember_token
SecureRandom.urlsafe_base64
end
def Account.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def init
if self.new_record?
if self.rem_notice_hrs.nil?
self.rem_notice_hrs = 24
end
if self.rem_text.nil?
if self.company.nil?
self.rem_text = "Dear [customer title: automatic] [customer family name: automatic], this is a reminder of your appointment with %{title} %{family_name} on [date/time]."
else
self.rem_text = "Dear [title] [customer family name], this is a reminder of your appointment with %{company} on [date/time]."
end
end
end
end
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
end
class Location < ActiveRecord::Base
belongs_to :coworker, :class_name => 'Coworker', :foreign_key => :wor_id
belongs_to :appointment, :class_name => 'Appointment', :foreign_key => :app_id
#optional deletion flag:
validates_inclusion_of :deleted, in: [true, false]
end
class Coworker < ActiveRecord::Base
include Person
validates_inclusion_of :deleted, in: [true, false]
belongs_to :account, :class_name => 'Account', :foreign_key => :acc_id
has_many :assignments
end
class Location < ActiveRecord::Base
belongs_to :coworker, :class_name => 'Coworker', :foreign_key => :wor_id
belongs_to :appointment, :class_name => 'Appointment', :foreign_key => :app_id
validates_inclusion_of :deleted, in: [true, false]
end
class Appointment < ActiveRecord::Base
belongs_to :customer, :class_name => 'Customer', :foreign_key => :cus_id
belongs_to :location, :class_name => 'Location', :foreign_key => :loc_id
belongs_to :appointment_type, :class_name => 'AppointmentType', :foreign_key => :app_type_id
has_many :assignments, :class_name => 'Assignment'
has_many :reminders, :class_name => 'Reminder'
validates_date :from, :on_or_after => :today
validates_date :till, :on_or_after => :from
validates_inclusion_of :deleted, in: [true, false]
attr_accessor :title
end
Some of the models above implement the following concerns:
module Contact
extend ActiveSupport::Concern
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
# phone attribute
included do
validates :phone, presence: true
validates :phone, numericality: true
attr_accessor :company
end
#email regex
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
end
module Person
extend ActiveSupport::Concern
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
included do
# deleted flag attribute
attr_accessor :first_name, :family_name, :title
end
end
Can you tell what's going wrong here?
This is a classical example of a copy-paste mess - I've copied the code of Location.rb into Assignment.rb, edited it but forgot to re-name the class. So I end up having two Location models - in 2 different rb files. Doh!
ever since i updated to rails 4 i've been struggeling with strong_params. I finaly tought i had it but now there seems to an unexpected_end some where. i think i overlook everything but it still seems to be wrong somewhere.
i'm very new to ruby on rails aswel.
user.rb
class User < ActiveRecord::Base
#attr_accessible :name, :email, :password, :password_confirmation
#attr_acessor :password
has_secure_password
before_save { self.email = email.downcase }
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :nickname, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:uniqueness => { :case_sensitive => false },
:format => { :with => email_regex }
validates :password, :presence => true,
end
users_controller.rb
class UsersController < ApplicationController
def new
#title = "Sign Up"
#user = User.new
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render "new"
end
end
private
def user_params
params.require(:user).permit(:nickname, :email, :password, :password_confirmation )
end
end
As per the comment, i.e., i forgot the comma at the end validates :password, :presence => true, OP has resolved the issue. I am just posting it as an answer (not expecting credit for the same) so SO community knows that the question is complete and answered.
You have an extra comma at the end of validates :password, :presence => true, which is causing the error.
Removing that would resolve your issue.
validates :password, :presence => true
models/user.rb
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :login
end
models/post.rb
class Post < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :user
attr_accessible :user_id, :description, :title
end
models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
attr_accessible :body, :user_id
end
I have installed 'strong_parameters'. And trying to make out with it. Can any one please guide me for model and controller code for the same.
Remove attr_accessible from models.
And in the controller, lets take the example of PostsController, create a private method post_params where you will define accessible attributes of Post model
class PostsController < ApplicationController
def update
#post = Post.find(params[:id])
if #post.update(post_params)
redirect_to #post, notice: 'Post was successfully updated.'
else
render "edit"
end
end
private
def post_params
params.require(:post).permit(:user_id, :description, :title)
end
end