I have a User model. A user can be an employer or a student. So there is an employer model and a student model. They both belong to user. Only employers can view student profiles. So if there is something wrong with the profile, the employer should be able to report the profile. I was thinking of having a "report" button on the profile which only the employers can see. Then when they click on it, the admin (me) gets an email with the url or the id of the student.
Right now, the student profile url looks like www.mywebsite.com/students/john-big. How can the report button be setup so the whole URL or the user-id (John-big) gets emailed to me.
The mailer is set up already because I set it up in a way where I get an email every time a user signs up. I can use the same logic to email myself, but grabbing the ID or url is the problem. What is the best way to do it?
Userinfo controller (userinfo =student):
class UserinfosController < ApplicationController
before_action :find_userinfo, only: [:show, :edit, :update, :destroy, :log_impression]
before_action :authenticate_user!
def index
end
def show
end
def new
#userinformation = current_user.build_userinfo
end
def create
#userinformation = current_user.build_userinfo(userinfo_params)
if #userinformation.save
redirect_to userinfo_path(#userinformation)
else
render 'new'
end
end
def edit
end
def update
if #userinformation.update(userinfo_params)
redirect_to userinfo_path(#userinformation)
else
render 'edit'
end
end
def destroy
#userinformation.destroy
redirect_to root_path
end
private
def userinfo_params
params.require(:userinfo).permit(:name, :email, :college, :gpa, :major)
end
def find_userinfo
#userinformation = Userinfo.friendly.find(params[:id])
end
end
Employer controller:
class EmployersController < ApplicationController
before_action :find_employer, only: [:show, :edit, :update, :destroy]
def index
end
def show
end
def new
#employer = current_user.build_employer
end
def create
#employer = current_user.build_employer(employer_params)
if #employer.save
redirect_to userinfos_path
else
render 'new'
end
end
def edit
end
def update
if #employer.update(employer_params)
redirect_to employer_path(#employer)
else
render 'edit'
end
end
def destroy
#employer.destroy
redirect_to root_path
end
private
def employer_params
params.require(:employer).permit(:paid, :name, :company, :position, :number, :email, :emp_img)
end
def find_employer
#employer = Employer.friendly.find(params[:id])
end
end
User model:
class User < ActiveRecord::Base
has_one :userinfo
has_one :employer
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
acts_as_messageable
after_create :welcome_send
def welcome_send
WelcomeMailer.welcome_send(self).deliver_now
end
end
Please let me know if you guys need more information.
I would use request.url() to get the URL of your view (the student profile url).
Try adding this to you view to get a feeling of it:
<%= debug("request.url: #{request.url()}") if Rails.env.development? %>
I hope this helps.
Related
My userinfos controller handles user information. As soon as the user signs up, I want them to go to the page that lets them fill out the user information like name, email, gpa, college...Lets just say they leave before completing the form, when they sign in again, I want to check if the user information has been filled out, if not, I want to take them to enter the new information page. What should I do to make that happen? I was told to add this code to the application
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def after_sign_in_path_for(resource)
if #userinformation.Userinfo.count.zero?
new_userinfo_path
else
root_path
end
end
def after_sign_up_path_for(resource)
if #userinformation.Userinfo.count.zero?
new_userinfo_path
else
root_path
end
end
end
But it doesn't work. Since "#userinformation" is an instance variable in the userinfos controller, and it's not related to the application controller, it doesn't work. I know the code is wrong in the above controller, but that's the logic I want. If there count of data in the Userinfo model of the particular user is 0, then I want to direct them to the "new_userinfo_path".
My Userinfo controller:
class UserinfosController < ApplicationController
before_action :find_userinfo, only: [:show, :edit, :update, :destroy]
def index
#userinfors = Userinfo.all
#myvideo = Video.all
end
def show
#myvideo = #userinformation.videos.last
end
def new
#userinformation = current_user.userinfos.build
end
def create
#userinformation = current_user.userinfos.build(userinfo_params)
if #userinformation.save
redirect_to userinfo_path(#userinformation)
else
render 'new'
end
end
def edit
end
def update
if #userinformation.update(userinfo_params)
redirect_to userinfo_path(#userinformation)
else
render 'edit'
end
end
def destroy
#userinformation.destroy
redirect_to root_path
end
private
def userinfo_params
params.require(:userinfo).permit(:name, :email, :college, :gpa, :major)
end
def find_userinfo
#userinformation = Userinfo.find(params[:id])
end
end
Userinfo model:
class Userinfo < ActiveRecord::Base
belongs_to :user
has_many :videos, through: :user
def info_complete?
name? && email? && college? && gpa? && major?
end
end
User model:
class User < ActiveRecord::Base
has_many :userinfos
has_many :videos
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Please tell me if you guys need anymore information to understand the question better.
So what I would do is instead of trying to count an instance object, I'd go to the userInfo model and create a method to check this. Would be something like this:
def info_complete?
name? && email? && college? && gpa? && major?
end
So now you've got a method that will return false unless all the fields in userInfo have a value (.e.g the form isn't complete and we should redirect them there).
So now we can go back to after_sign_in_path method and query the resource
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def after_sign_in_path_for(resource)
# I'm not too sure how userInfo relates to a user in your app
if resource.userinfo.info_complete?
redirect_to root_path
else
redirect_to new_userinfo_path
end
end
end
Hope this helps.
Use the association between User and Userinfo to check if the user has any user_infos.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def after_sign_in_path_for(resource)
if resource.userinfos.empty?
new_userinfo_path
else
root_path
end
end
end
Why not simply redirect the user in your SignUpController or SignInController actions?
class SignUpController < ApplicationController
// ...
def create
// Sign up... the user probably won't have any userinfos yet.
redirect_to new_userinfo_path
end
// ...
end
class SignInController < ApplicationController
// ...
def create
// Sign up... the user probably won't have any userinfos yet.
if #userinformation.userinfo.count.zero?
redirect_to new_userinfo_path
else
redirect_to root_path
end
end
// ...
end
I'm new to Rails and I'm stuck at something really silly. I was trying to make an app where users can post pinterest-like pins, so I went with user has_many: pins and pin belongs_to: user. Here's the codes from a few files just to give you an idea of what state I'm in right now:
app/models/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
has_many :pins
end
app/models/pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
end
pins_controller.rb
class PinsController < ApplicationController
before_action :find_pin, only: [:show, :edit, :update, :destroy]
def index
#pins = Pin.all.order("created_at DESC")
end
def show
end
def new
#pin = current_user.pins.build
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: "Successfully created new Pin"
else
render 'new'
end
end
def edit
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: "Pin was successfully updated!"
else
render 'edit'
end
end
def destroy
#pin.destroy
redirect_to root_path
end
def error
end
private
def pin_params
params.require(:pin).permit(:title, :description)
end
def find_pin
#pin = Pin.find(params[:id])
end
end
/views/pins/show.html.haml
%h1= #pin.title
%p= #pin.description
%p
%hr
%strong Submitted by
= #pin.user.email
Here, in the last line of show.html.haml, I want the #pin.user.email to be a link so that
the profile of the user (the one who submitted the article) can be accessed when clicked on it.
the profile of the user should list all of the articles submitted by him/her.
These are the two things that I'm trying to accomplish but don't know the code I should use for it. I don't have a users_controller. I did have one but I deleted it after it started messing with devise's routes. All answers are welcome, thanks in advance!
First Of All Create User Controller.
Redirect Show page line to user show action
Then you perform what you want.
For Ex.
link_to "User Profile", user_path(#pin.user.id)
users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find_by_id(params[:id])
#pins = #user.pins
end
end
/views/users/show.html.haml
User #user and #pins to Display What you want.
You forgot to define your show method
def show
#pin
end
I am using Devise for registration. But I want to build a profile for user so that where user can fill their info.
I want a single for profile for user but whenever new_profile_path another profile is created for that user, I want to avoid user to go to new_profile_path or create new profile after 1 profile is created.
here is the code
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
has_one :profile
has_many :statuses
end
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
validates_associated :user
end
profiles_controller.erb
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :find_profile, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#profiles = Profile.all
end
def new
#profile = Profile.new
end
def create
#profile = Profile.new(profile_params)
#profile.user_id = current_user.id
#profile.save
respond_with(#profile)
end
def show
#profile = Profile.find(params[:id])
end
def edit
end
def update
#profile.update(profile_params)
respond_with(#profile)
end
private
def find_profile
#profile = Profile.find(params[:id])
end
def profile_params
params.require(:profile).permit(:first_name, :last_name, :birth_date,
:gender, :bio, :personal_website, :linkedin_profile, :facebook_profile,
:mobile_no, :telephone_no)
end
end
This is the current code for creating Profile for user. But every time a profile is created for user through new_profile_path. How can I avoid it?
Thanks in advance for giving your time.
One solution is:
# in User model
has_one :profile
before_create :build_profile, unless: :profile
Alternatively:
# in User model
has_one :profile
after_create :create_profile, unless: :profile
The conditional unless: :profile is there so that it doesn't overwrite a profile that was already added before the user was created.
When your using associations, you have to use build instead of new.... In your Profile controller...
def new
#profile = current_user.build_profile
end
def create
#profile = current_user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile saved"
redirect_to current_user_path
else
flash[:error] = "Error"
render: new
end
end
This will make sure that only one profile is created for each user...
def edit
#profile = current_user.profile.find(params[:id])
end
def update
#profile = current_user.profile.find(params[:id])
if #profile.update_attributes(profile_params)
flash[:success] = "Successfully updated" # Optional
redirect_to user_path
else
flash[:error] = "Error" # Optional
render :edit
end
end
I have a basic rails app with devise set up and a profile model generated with scaffolding. The Profile model is where the user will add detailed information about themselves after they sign up. Everything is working fine except for one issue: after the user creates a profile, the new profile is created however it is not linked to that user id. I have generated the migration to add user_id to profile. How can I make the profile that the user creates get saved and linked to the currently signed in user?
here is my current code:
Profiles controller:
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :set_profile, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#profiles = Profile.all
respond_with(#profiles)
end
def show
#profile = Profile.find(params[:id])
respond_with(#profile)
end
def new
#profile = Profile.new
respond_with(#profile)
end
def edit
end
def create
#profile = Profile.new(profile_params)
#profile.save
respond_with(#profile)
end
def update
#profile.update(profile_params)
respond_with(#profile)
end
def destroy
#profile.destroy
respond_with(#profile)
end
private
def set_profile
#profile = Profile.find(params[:id])
end
def profile_params
params.require(:profile).permit(:name, :civil, :email, :level, :employment_date, :mobile, :folder, :title, :internal, :nationality, :vacation, :work_email, :experience)
end
end
Profile model:
class Profile < ActiveRecord::Base
belongs_to :user
validates_associated :user
end
User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile
end
As long as you use devise, it should be as simple as:
class ProfilesController < ApplicationController
def create
#profile = Profile.new(profile_params)
#profile.user_id = current_user.id
#profile.save
respond_with(#profile)
end
end
Devise creates that helper method for you. Check its docs page.
I have 2 controllers User and Rota. I want the user to be able to create their own Rota but only be able to edit, show and destroy their own. I need to be able to code so that my rotum object belongs to the user object.
ROTA CONTROLLER:
class RotaController < ApplicationController
respond_to :html, :xml, :json
before_action :set_rotum, only: [:show, :edit, :update, :destroy]
def edit
#rotum = #user.rota.find params[:id]
end
def index
#rota = Rotum.all
respond_with(#rota)
end
def show
respond_with(#rotum)
end
def new
#rotum = Rotum.new
respond_with(#rotum)
end
def edit
end
def create
#rotum = Rotum.new(rotum_params)
#rotum.save
respond_with(#rotum)
end
def update
#rotum.update(rotum_params)
respond_with(#rotum)
end
def destroy
#rotum.destroy
respond_with(#rotum)
end
private
def set_rotum
#rotum = current_user.rotums.find(params[:id])
if #rotum.nil?
render :html => "Not authorized", :status => 401
end
end
def rotum_params
params.require(:rotum).permit(:name, :email, :mobile, :category)
end
end
USER CONTROLLER
class UsersController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized
def index
#users = User.all
authorize User
end
def show
#user = User.find(params[:id])
authorize #user
end
def update
#user = User.find(params[:id])
authorize #user
if #user.update_attributes(secure_params)
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
def destroy
user = User.find(params[:id])
authorize user
user.destroy
redirect_to users_path, :notice => "User deleted."
end
def edit
#rotum = #user.rota.find params[:id]
end
private
def secure_params
params.require(:user).permit(:role)
end
end
So far my rota allows anyone to create, show, edit and destroy the rota on the rotas page. I only want the user to be able to edit only THEIR OWN rota that they created. For that I have been told tell the rota object to belong to the user object. How can I do this in my controllers or models.
USER MODEL
class User < ActiveRecord::Base
has_many :rota, dependent: :destroy
enum role: [:user, :vip, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :user
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
ROTUM MODEL
class Rotum < ActiveRecord::Base
belongs_to :user
end
I get the error:
NoMethodError at /rota/15
undefined method `rotums' for #
You are not showing your models, so I'm assuming that you have a has_many relationship
class User < ActiveRecord::Base
has_many :rota, dependent: :destroy
end
class Rotum < ActiveRecord::Base
belongs_to :user
end
then in your controller you can use the following:
class UsersController < ApplicationController
....
def edit
#rotum = #user.rota.find params[:id]
end
Note that this will raise an ActiveRecord::RecordNotFound exception if a user is triying to edit a rotum that does not belong to him.
You can avoid that problem with the following:
class UsersController < ApplicationController
....
def edit
#rotum = #user.rota.find_by id: params[:id] # returns nil in case the record does not exist or does not belong to #user
redirect_to "somewhere", alert: 'You cannot edit this element' if #rotum.blank?
end