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
Related
I’m using Rails 4.2.3. I have this in my user_controller.rb …
def update
#user = current_user
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to url_for(:controller => 'races', :action => 'index') and return
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :dob, :address, :automatic_import)
end
and when my parameters get submitted to “update,”
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bz24jRzK5qVWolW0oBoQbniiaQi96MeFFmzNjB4kCr0ifUYSsitvQIyod5AWDJd4KS3lrt3mzLiG8F9ef3aJkg==", "user"=>{"first_name"=>"Anthony", "last_name"=>"Alvarado", "dob(2i)"=>"1", "dob(3i)"=>"14", "dob(1i)"=>"1908", "address"=>{"city"=>"chicago"}, "automatic_import"=>"0"}, "state"=>"CT", "country"=>{"country"=>"233"}, "commit"=>"Save", "id"=>"13"}
Unpermitted parameter: address
Why am I getting this unpermitted parameter message when it is included in my “require” statement above? I even have this in my app/models/user.rb file …
class User < ActiveRecord::Base
…
belongs_to :address
There are 2 issues that are linked. (My assumption is that the user has one address, and not that the address has one user.) The model relationship should be:
class User < ActiveRecord::Base
…
has_one :address
accepts_nested_attributes_for :address
The address model:
class Address < ActiveRecord::Base
…
belongs_to :user
This should eliminate the unpermitted parameter error for address.
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
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!
I am following the HABTM Railscast #17 on using checkboxes to create associated records using a join table.
I finally got my records to save to the join table....but I can't control them by checking or unchecking a box....meaning unchecking the record does nothing and leaving the record checked makes ANOTHER duplicate record.
I have 3 tables.
:project has_many :restrictions, :through => :project_restrictions
What I'd like to be able to do is have an array of checkboxes that I can check to create :project_restrictions...or, if I uncheck them, the remove the :project_restriction record.
Right now it just keeps saving multiple records and does not delete them if I uncheck one.
I have put all my logic in the ProjectsController and am running the method for adding the :project_restrictions through a custom PATCH method called "add_restrictions". Should this be a POST? I can't figure out if I'm PATCHING Project by adding associated records or POSTING just the associated records.
my join table has an :id and no :timestamps .... I don't know if this matters....obviously, I'm new.
I am using rails 4.
MY MODELS
class Project < ActiveRecord::Base
has_many :project_restrictions, dependent: :destroy
has_many :restrictions, :through => :project_restrictions
accepts_nested_attributes_for :project_restrictions, allow_destroy: true, :reject_if => :all_blank
class Restriction < ActiveRecord::Base
has_many :projects, :through => :project_restrictions
has_many :project_restrictions, dependent: :destroy
class ProjectRestriction< ActiveRecord::Base
belongs_to :restriction
belongs_to :project
end
**My PATCH Controller Method to Create Associated Records **
def add_restrictions
#diet = Restriction.k1.order(:name)
#project = Project.find(params[:p])
params[:project][:restriction_ids].reject!(&:empty?).each do |restriction|
#proj_rule = ProjectRestriction.create!(:project_id => #project.id, :restriction_id => restriction)
#proj_rule.save
end
respond_to do |format|
format.html { redirect_to t1s3_path(:p => #project.id ) ,
notice: 'Success! You added restrictions!' }
format.json {}
end
end
And my form
<%= form_for #project, url: add_restrictions_path(:p => #project.id) do |f| %>
<div class=" fields ">
<%= hidden_field_tag "project[restriction_ids][]", nil %>
<% #diet.each do |restriction| %>
<%= check_box_tag "project[restriction_ids][]", restriction.id,
#project.restriction_ids.include?(restriction.id), id: dom_id(restriction)%>
<%= label_tag dom_id(restriction), restriction.name %><br>
<% end %>
</div>
<%= f.submit %>
UPDATE:
I have updated my Models to have "uniq and inverse_of ....however I'm still creating duplicate records and unable to destroy them by unchecking the checkbox
class Project < ActiveRecord::Base
has_many :project_restrictions -> { uniq }, dependent: :destroy, inverse_of: :project
has_many :restrictions, -> { uniq }, through: :project_restrictions
accepts_nested_attributes_for :project_restrictions, allow_destroy: true, :reject_if => :all_blank
class Restriction < ActiveRecord::Base
has_many :projects, -> { uniq }, through: :project_restrictions
has_many :project_restrictions, -> { uniq }, dependent: :destroy, inverse_of: :restriction
class ProjectRestriction< ActiveRecord::Base
belongs_to :restriction, -> { uniq }, inverse_of: :project_restrictions
belongs_to :project, -> { uniq }, inverse_of: :project_restrictions
end
change this in your add_restrictions method and try
def add_restrictions
#diet = Restriction.k1.order(:name)
#project = Project.find(params[:p])
params[:project][:restriction_ids].reject!(&:empty?).each do |restriction|
#projectrestrictions = ProjectRestriction.all
#projectrestrictions.each do |prj|
if prj.restriction_id == restriction
ProjectRestriction.destroy_all(prj.id)
else
#proj_rule = ProjectRestriction.create!(:project_id => #project.id, :restriction_id => restriction)
#proj_rule.save
end
end
respond_to do |format|
format.html { redirect_to t1s3_path(:p => #project.id ) ,
notice: 'Success! You added restrictions!' }
format.json {}
end
end
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