Having trouble counting page views using "impressionist" gem (Ruby on Rails) - ruby-on-rails

Update #2
I've got it working but how can I make it count each refresh? Even if I refresh on a user's profile (/users/3 for example), I want it to count.
Widget.rb
class Widget < ActiveRecord::Base
is_impressionable
def impressionist_count
impressions.size
end
end
Widgets controller
WidgetsController < ApplicationController
def show
#widget = Widget.find(params[:id])
impressionist(#widget,message:"wtf is a widget?") #message is optional
end
end
Added Is_Impressionable to the user model
and here's the code I'm using for show.html.erb view
<%= #user.impressionist_count(:filter=>:all) %>
Update #1
When I make the change noted below in Said's answer and try it in the "Widgets" controller and "Widget" module, I get this error now:
NoMethodError in Users#show
undefined method `impressionist_count' for nil:NilClass
Here's the user.rb
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
has_many :microposts, dependent: :destroy
has_many :impressions, :as=>:impressionable
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
before_save { |user| user.email = user.email.downcase }
before_save :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 }
validates :password_confirmation, presence: true
def following?(other_user)
relationships.find_by_followed_id(other_user.id)
end
def follow!(other_user)
relationships.create!(followed_id: other_user.id)
end
def unfollow!(other_user)
relationships.find_by_followed_id(other_user.id).destroy
end
def feed
Micropost.from_users_followed_by(self)
end
def impressionist_count
impressions.size
end
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
and here's the Users controller
class UsersController < ApplicationController
before_filter :signed_in_user,
only: [:index, :edit, :update, :destroy, :following, :followers]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page]).all
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Demoapp!"
redirect_to root_url
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(params[:user])
sign_in #user
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed"
redirect_to users_path
end
def following
#title = "Follow"
#user = User.find(params[:id])
#users = #user.followed_users.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Following"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def correct_user
#user = User.find(params[:id])
redirect_to root_path unless current_user?(#user)
end
def admin_user
redirect_to root_path unless current_user.admin?
end
end
Original Post
What did I do wrong below?
I added the gem and ran the db migration.
Then I created a new "Widgets" controller file in app\controllers
WidgetsController < ApplicationController
def show
#widget = Widget.find
impressionist(#widget)
end
end
Then I created a new "Widget" model in app/models
class Widget < ActiveRecord::Base
is_impressionable
end
Then I added
<%= #widget.impressionist_count %>
in the show.html.erb view
What I am trying to count is the # of user's profile views. Throughout the website, you can click on a username and it will go into their profile. I just want to show the counter of how many times were clicked into their profile.
Thanks

Seems the problem is in show action,
instead:
#widget = Widget.find
try this
#widget = Widget.find(params[:id])
UPDATE: 1
you should add is_impressionable to your user model

Related

How do I create a page without a model?

I'm working on an app which has many 'Activities'. Each 'Activity' has many 'Ranks'. I'd like each 'Activity' to have a page called grading, where the user can see a list of all of that activity's ranks and conveniently update them. I imagine the URL would be something like http://localhost:3000/activities/21/grading
I'm already using http://localhost:3000/activities/21/edit for its intended purpose.
I don't need a model for gradings, as I don't need to save any grading records.
I know exactly what to put in the view, I'm just unsure what to add to the controller and routes files. Other people have worked on this app but I'm unable to contact them.
Routes
resources :activities do
collection do
get 'scheduled_classes'
end
end
resources :ranks
end
activities_controller
class ActivitiesController < ApplicationController
def new
#activity = Activity.new
#activity.timeslots.build
#activity.ranks.build
end
def create
#activity = current_club.activities.new(activity_params)
if #activity.save
flash[:success] = "New class created!"
redirect_to activity_path(#activity)
else
render 'new'
end
end
def edit
#activity = current_club.activities.find_by(id: params[:id])
#active_ranks = #activity.ranks.where(active: true)
if !#activity.active?
redirect_to activities_path
else
#activity.timeslots.build
end
end
def update
#activity = current_club.activities.find_by(id: params[:id])
if #activity.update_attributes(activity_params)
flash[:success] = "Class updated!"
redirect_to edit_activity_path(#activity)
else
render 'edit'
end
end
def show
#activity = current_club.activities.find_by(id: params[:id])
#active_ranks = #activity.ranks.where(active: true)
if #activity.nil?
redirect_to root_url
elsif !#activity.active?
redirect_to activities_path
end
end
def index
#activities = current_club.activities.all
end
def destroy
#activity = current_club.activities.find_by(id: params[:id])
if #activity.nil?
redirect_to root_url
else
#activity.destroy
flash[:success] = "Class deleted"
redirect_to activities_path
end
end
end
private
def activity_params
params.require(:activity).permit(:name, :active,
:timeslots_attributes => [:id,
:time_start,
:time_end,
:day,
:active,
:schedule],
:ranks_attributes => [:id,
:name,
:position,
:active])
end
end
activity
class Activity < ApplicationRecord
belongs_to :club
has_many :timeslots, dependent: :destroy
accepts_nested_attributes_for :timeslots,:allow_destroy => true
has_many :ranks, dependent: :destroy
has_many :attendances, dependent: :destroy
accepts_nested_attributes_for :ranks
validates :club_id, presence: true
validates :name, presence: true, length: { maximum: 50 }
end
Your routes don't need to have an associated model or resource.
resources :activities do
collection do
get 'scheduled_classes'
end
member do
get :grading
end
end
will match to activities#grading
See https://guides.rubyonrails.org/routing.html#adding-member-routes for more info.
As you want to add a route on a particular activity, you should add member route on the activity like below,
resources :activities do
collection do
get 'scheduled_classes'
end
get :grading, on: :member
end
Apart from this, you have to add method in ActivitiesController for this route like below,
def grading
#activity = Activity.find_by(id: params[:id])
# do more here
end
In view files, you can create grading.html.erb under activities resources and put your view code there.

Rails match ? attribute_missing(match, *args, &block) : super, NoMethodError in StaticPagesController#home

I am trying to modify Michael Hartl sample app from railstutorial.
My static_pages controller looks like that:
class StaticPagesController < ApplicationController
def home
if logged_in?
#micropost = current_user.microposts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
def help
end
def about
end
def contact
end
end
and a Im geting error mesage like this:
NoMethodError in StaticPagesController#home
undefined method `microposts' for #<User:0x00000004d39d58>
else
match = match_attribute_method?(method.to_s)
match ? attribute_missing(match, *args, &block) : super
end
end
user model:
class User < ActiveRecord::Base
has_many :listings, :class_name => "Micropost", :foreign_key => "seller_id", dependent: :destroy
has_many :bids, foreign_key: "bidder_id"
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
attr_accessor :remember_token, :activation_token, :reset_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: {case_sensitive: false}
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
def to_s
self.name
end
# Returns the hash digest of the given string.
def User.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def User.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
# Sets the password reset attributes.
def create_reset_digest
self.reset_token = User.new_token
update_attribute(:reset_digest, User.digest(reset_token))
update_attribute(:reset_sent_at, Time.zone.now)
end
# Sends password reset email.
def send_password_reset_email
UserMailer.password_reset(self).deliver_now
end
# Returns true if a password reset has expired.
def password_reset_expired?
reset_sent_at < 2.hours.ago
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
# Defines a proto-feed.
# See "Following users" for the full implementation.
# Returns a user's status feed.
def feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Micropost.where("seller_id IN (#{following_ids})
OR seller_id = :seller_id", seller_id: id)
end
# Follows a user.
def follow(other_user)
active_relationships.create(followed_id: other_user.id)
end
# Unfollows a user.
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# Returns true if the current user is following the other user.
def following?(other_user)
following.include?(other_user)
end
private
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
user controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#micropost = #user.microposts.build
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
I not sure is this problem related to controller implementation or views or meybe microposts implementations. Please gyus help for complete rails noob
The first line in your model is:
class User < ActiveRecord::Base
has_many :listings, :class_name => "Micropost", :foreign_key => "seller_id", dependent: :destroy
In your User Model you should have:
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
You have defined:
has_many :listings, :class_name => "Micropost", :foreign_key => "seller_id"
So you must use:
#micropost = current_user.listings.build
Instead of yours:
#micropost = current_user.microposts.build
The reason is Rails takes :listings as the 'official name' of the relation.
When you specify :class_name => "Micropost" - for Rails that means the actual name.
So you can use as many official names as you want for one actual dependence.

Can only create one user profile - Rails 4.2.4

I'm using devise for my user auth and registration. I can register a user no problem. Im also using friendly. My issue is, I can only create one user profile.
The setup...
user.rb:
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
validates :name, uniqueness: true, presence: true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile # each user should have just one profile
end
profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
end
profiles_controller.rb:
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :only_current_user
def new
# form where a user can fill out their OWN profile
#user = User.friendly.find( params[:user_id] )
#profile = Profile.new
end
def create
#user = User.friendly.find( params[:user_id] )
#profile = #user.build_profile(profile_params)
if #profile.save # Not saving!!
flash[:success] = 'Profile Created!'
redirect_to user_path( params[:user_id] )
else
render action: :new # keeps rendering!
end
end
private
def profile_params
params.require(:profile).permit(:first_name, :last_name, :avatar, :job_title, :phone_number, :business_name)
end
end
Why is it that only one user can create a profile and not others? Is it has to do with the relations?
We use this setup with some of our apps - User -> Profile.
In short, you should build the profile at User creation. Then you can edit the profile as you need. Your problem of having a Profile.new method is very inefficient...
#app/models/user.rb
class User < ActiveRecord::Base
has_one :profile
before_create :build_profile #-> saves blank associated "Profile" object after user create
end
This will mean that each time a User is created, their corresponding Profile object is also appended to the db.
This will give you the capacity to edit the profile as required:
#config/routes.rb
resources :users, path_names: { edit: "profile", update: "profile" }, only: [:show, :edit, :update]
This will give you the opportunity to use the following:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:edit, :update]
before_action :authorize, only: [:edit, :update]
def show
#user = User.find params[:id]
end
def edit
#user = current_user
end
def update
#user = current_user
#user.update user_params
end
private
def authorize
id = params[:id]
redirect_to user_show_path(id) if current_user.id != id #-> authorization
end
def user_params
params.require(:user).permit(:x, :y, :z, profile_attributes: [:homepage, :other, :profile, :attributes])
end
end
The view/form would be the following:
#app/views/users/edit.html.erb
<%= form_for #user do |f| %>
<%= f.fields_for :profile do |f| %>
<%= f.text_field :homepage %>
...
<% end %>
<%= f.submit %>
<% end %>
In regards your current setup:
def new
#profile = current_user.profile.new
end
def create
#profile = current_user.profile.new profile_params
if #profile.save
redirect_to user_path(params[:id]), notice: "Profile Created!"
else
render action: :new
end
end
private
def profile_params
params.require(:profile).permit(:x, :y, :z)
end
Not sure why you don't create the profile in the after_create event of the user. As soon the user is created - create an empty (but associated) profile.
class User
has_one :profile, dependent: :destroy
after_create {
build_profile unless profile
profile.save
}
end
class Profile
belongs_to :user, autosave: true
end
so then, in your controller you just need the update method.
def update
if current_user.profile.update_attributes(user_params)
flash_it :success
return redirect_to edit_user_profile_path
else
flash_it :error
render :edit
end
end

Setting an id as a default foreign key in rails

I am having challenges assigning a current user a role in a team the user is creating. I want to assign the user that creates the team the role of the captain which could be changed later.
I'm currently using the create_asociation method that comes with has_one relationship, as this instantiates the values of the associated model, which i want to be instantiated with the current user but get the error Can't mass assign protected attribute: captain. Captain is a self join model with user as i will like to use captain.teammates and team.captain.
Below are the models involved.
User and Captain Model
class User < ActiveRecord::Base
has_one :profile
has_many :teammates, :class_name => "User", :foreign_key => "captain_id"
belongs_to :captain, :class_name => "User"
belongs_to :team
# before_create :build_profile
after_create :build_default_profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password, :password_confirmation, :profile_attributes, :captain_id
def build_default_profile
Profile.create(user_id: self.id)
end
has_secure_password
before_save { email.downcase! }
before_save :create_remember_token
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
Team Model
class Team < ActiveRecord::Base
has_many :profiles, through: :users
has_one :captain, :class_name => "User", foreign_key: :captain_id
has_one :result, as: :result_table
attr_accessible :teamname, :color, :result_attributes, :captain_attributes
after_create :build_result_table
after_create :build_default_captain
accepts_nested_attributes_for :profiles
accepts_nested_attributes_for :captain
accepts_nested_attributes_for :result
def build_result_table
Result.create(result_table_id: self.id, result_table_type: self.class.name)
end
def build_default_captain
# Team.captain = User
# Captain.create(team_id: self.id, captain_id: user.id)
end
end
User Controller
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update, :destroy]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save!
sign_in #user
flash[:success] = "Welcome to the JHDC Mini Olympics Web Application; Thanks for singing Up"
redirect_to user_profile_path(#user, #profile)
else
flash[:error_messages]
render 'new'
end
end
def show
#user = User.find(params[:id])
end
def index
#users = User.paginate(page: params[:page])
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Profile Updated"
redirect_to user_profile_path(#user, #profile)
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted."
redirect_to users_url
end
private
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in."
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
end
Team Controller
class TeamsController < ApplicationController
def new
#team = Team.new
end
def create
#team = Team.new(params[:team])
#captain = #team.create_captain(captain: current_user)
if current_user.admin?
if #team.save!
flash[:success] = "Team created."
redirect_to #team
else
flash[:error_messages]
render 'new'
end
else
flash[:error] = "Sorry, you don't have the authority to create a Team"
redirect_to current_user
end
end
def index
#teams = Team.paginate(page: params[:page])
end
def show
#team = Team.find(params[:id])
end
def edit
if current_user.admin?
#team = Team.find(params[:id])
else
flash[:error] = "Sorry you dont have the authourity to edit a Team"
redirect_to current_user
end
end
def update
#team = Team.find(params[:id])
if #team.update_attributes(params[:team])
flash[:success] = "Team Updated"
redirect_to #team
else
render 'edit'
end
end
def destroy
Team.find(params[:id]).destroy
flash[:success] = "Team is deleted."
redirect_to teams_url
end
private
def team_params
params.require(:team).permit(:teamname, :color)
end
end
The admin is currently a way i'm using to restrict the user that can create a team but i plan to use gems like declarative authorization to create role based authorization. Thanks
The error you are getting is because the attribute :captain is not declared as attr_accessible
Either set the attribute :captain in your list of attr_accessible for the User model, or change the code form
Captain.create(team_id: self.id, captain_id: user.id)
to
captain = Captain.new
captain.team_id = self.id
captain.captain_id = user.id
captain.create
in this way, the attribute won't be set by mass-assignment and won't raise the error
Edited
After checking your code twice, just realized that you don't have a Captain model, actually :captain is a relation for the user and a relation from the Team to the User.
So on Team model, take off the build_default_captain stuff and the after_create :build_default_captain, I would say to replace with something like
after_save :set_default_captain
def set_default_captain
if captain_id_changed?
profiles.each do |user|
user.captain = captain
user.save
end
end
end
so every time the captain_id change for the model, you change the captain_id of all its profiles (users)
Then on the Team controller, on the action create, instead of
#team = Team.new(params[:team])
#captain = #team.create_captain(captain: current_user)
do something like
#team = Team.new(params[:team])
#team.captain = current_user
if current_user.admin?
if #team.save!
current_user.update_attribute(:team_id, #team.id)
flash[:success] = "Team created."
redirect_to #team
else
flash[:error_messages]
render 'new'
end
else
flash[:error] = "Sorry, you don't have the authority to create a Team"
redirect_to current_user
end
so on the last part of the code, you set the captain of the team to the current user and set the user team to the current team once its saved, you can also improve the code with current_user.build_team to avoid saving current_user.update_attribute

Default boolean value not being set Rails 4 Postgres

I have created a migration to my users table with the following code:
add_column :users, :email_confirmed, :boolean, :default => false
however when a new user is created the :email_confirmed field is automatically set to true. Has this happened to anyone? Am I missing something simple? Any insights are welcome.
My User model:
class User < ActiveRecord::Base
has_many :microposts, dependent: :destroy
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
has_secure_password
before_save { email.downcase! }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
before_create :create_remember_token
before_create :confirmation_token
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 }, :unless => :email_activate
def feed
Micropost.from_users_followed_by(self)
end
def following?(other_user)
relationships.find_by(followed_id: other_user.id)
end
def follow!(other_user)
relationships.create!(followed_id: other_user.id)
end
def unfollow!(other_user)
relationships.find_by(followed_id: other_user.id).destroy
end
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.digest(token)
Digest::SHA1.hexdigest(token.to_s)
end
def email_activate
self.email_confirmed = true
save!(:validate => false)
end
def send_password_reset
self.password_reset_token = SecureRandom.urlsafe_base64.to_s
self.password_reset_sent_at = Time.zone.now
save!(:validate => false)
UserMailer.password_reset(self).deliver
end
private
def create_remember_token
self.remember_token = User.digest(User.new_remember_token)
end
def confirmation_token
# only generate if you did not manually set value
if self.confirm_token.blank?
self.confirm_token = SecureRandom.urlsafe_base64.to_s
end
end
end
and my Users Controller:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
before_action :registered_already, only: [:new, :create]
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
UserMailer.registration_confirmation(#user).deliver
flash[:success] = "Please confirm your email address to continue"
redirect_to root_url
else
flash[:error] = "Ooooppss, something went wrong!"
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def destroy
user = User.find(params[:id])
unless current_user?(user)
user.destroy
flash[:success] = "User deleted."
end
redirect_to users_url
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.followed_users.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
def confirm_email
user = User.find_by_confirm_token(params[:id])
if user
user.email_activate
flash[:success] = "Welcome to the Sample App!"
redirect_to root_url
else
flash[:error] = "Sorry. User does not exist"
redirect_to root_url
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def registered_already
redirect_to root_url, notice: "You are already registered." if signed_in?
end
end
my Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email].downcase)
if user && user.authenticate(params[:password])
if user.email_confirmed
sign_in user
redirect_back_or user
else
flash.now[:error] = 'Please activate your account by following the
instructions in the account confirmation email you receieved to proceed'
end
else
flash.now[:error] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
sign_out
redirect_to root_url
end
end
I have a feeling that the email_activate method in the users model is being called on the create action but I don't know why?....
Just while I was doing this I commented out the `:unless => :email_activate' in the password validator. Now everything works. I am surprised that this was the reason as it does not make logical sense to my (admittedly somewhat limited) understanding of rails. Could someone explain why this was setting the email confirmed field to true please?
If you want the default value to always be set, you can't allow null values. Specify :null => false
add_column :users, :email_confirmed, :boolean, :null => false, :default => false

Resources