Ruby on Rails assign company_id and job_id in models - ruby-on-rails

Have three models: Company, Job and JobApplications. When submitting the job form, the company_id and job_id are showing up as nil in the rails console. What's the best way to assign both company_id and job_id values for each job created by a company?
I've added the company_id and job_id to the companies and jobs tables. Within the create method of my jobs model, I've assigned #company_id to the job params and company_id and job_id are still showing as nil after creating a job.
Controller Actions
class CompaniesController < ApplicationController
def new
#company = current_user.build_company
end
def create
#job = Job.new
#company = Company.new(company_params)
end
private
def set_company
#company = Company.find(params[:id])
end
def company_params
params.require(:company).permit(:avatar, :name, :website, :about)
end
class JobsController < ApplicationController
def new
#job = Job.new(:company_id => params[:id])
#company_id = params[:job][:company_id]
end
def create
# #job = current_user.jobs.build(job_params)
#job = Job.find(params[:job_id])
# #company = #job.company
#job = Job.create(job_params.merge(user: current_user, company_id: current_user, job_id: #job))
#company_id = params[:job][:company_id]
end
private
def set_job
#job = Job.find_by(id: params[:id])
if #job.nil?
redirect_to jobs_path
end
end
def job_params
params.require(:job).permit(:company_name, :company_website, :company_description, :company_avatar, :title, :location, :salary, :job_author, :remote_role, :job_type, :rounds_of_interviews, :start_date, :qualifications, :description, :benefits, :job_id)
end
class JobApplicationsController < ApplicationController
def create
#job_application = JobApplication.new(job_application_params)
#job_application.user_id = current_user.id
end
private
def set_job
#job = Job.find(params[:job_id])
# self.job_id
end
def job_application_params
params.permit(:first_name, :last_name, :email, :phone, :attachment, :work_for_any_employer, :require_visa_sponsorship)
end
Models
class Company < ApplicationRecord
has_many :conversations
has_many :jobs
has_many :job_applications, through: :jobs
end
class Job < ApplicationRecord
belongs_to :user
belongs_to :company, optional: true
has_many :job_applications, dependent: :destroy
end
class JobApplication < ApplicationRecord
belongs_to :user
belongs_to :job
validates_uniqueness_of :user_id, scope: :job_id
end

Related

undefined method `reviews' for #<Post:0x007fa207cb7c70>

I'm following a tutorial on how to implement reviews for my rails app, users can add reviews for posts. But when i click add new review i get 'NoMethodError in Reviews#new'
Reviews controller
class ReviewsController < ApplicationController
before_action :find_post
def new
#review = Review.new
end
def create
#review = Review.new(review_params)
#review.post_id = #post.id
#review.user_id = current_user.id
if #review.save
redirect_to post_path(#post)
else
render 'New'
end
end
private
def review_params
params.require(:review).permit(:rating, :comment)
end
def find_post
#post = Post.friendly.find(params[:post_id])
end
end
Review model
class Review < ApplicationRecord
belongs_to :post
belongs_to :user
end
Post model
class Post < ApplicationRecord
extend FriendlyId
belongs_to :user
friendly_id :title, use: :slugged
validates_presence_of :title , :description
end
It looks like you forgot has_many :reviews in your Post model.

RoR: Save information from 3 models at same time

I am trying to make it so that when I save an answer, I also save the prop_id that is associated with that answer.
I have a nested route relationship so that each prop (stands for proposition or bet) has a an associated answer like this: http://localhost:3000/props/1/answers/new.
Right now, when I save an answer, I save the answer choice and the user_id who created the answer. I need to save also the prop that is associated with the answer.
Answers Controller:
class AnswersController < ApplicationController
attr_accessor :user, :answer
def index
end
def new
#prop = Prop.find(params[:prop_id])
#user = User.find(session[:user_id])
#answer = Answer.new
end
def create
#prop = Prop.find(params[:prop_id])
#user = User.find(session[:user_id])
#answer = #user.answers.create(answer_params)
if #answer.save
redirect_to root_path
else
render 'new'
end
end
def show
#answer = Answer.find params[:id]
end
end
private
def answer_params
params.require(:answer).permit(:choice, :id, :prop_id)
end
Answer Model
class Answer < ActiveRecord::Base
belongs_to :prop
belongs_to :created_by, :class_name => "User", :foreign_key => "created_by"
has_many :users
end
Prop Model
class Prop < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :answers
end
User Model
class User < ActiveRecord::Base
has_many :props
has_many :answers
has_many :created_answers, :class_name => "Answer", :foreign_key => "created_by"
before_save { self.email = email.downcase }
validates :username, presence: true, uniqueness: {case_sensitive: false}, length: {minimum: 3, maximum: 25}
has_secure_password
end
Just modify your code a little bit, and it will work:
def create
#user = User.find(session[:user_id])
#prop = #user.props.find_by(id: params[:prop_id])
#answer = #user.answers.build(answer_params)
#answer.prop = #prop
# Modify #user, #prop or #answer here
# This will save #user, #prop & #answer
if #user.save
redirect_to root_path
else
render 'new'
end
end

Modeling Event Booking Process

New to stack! so Hello there ! I'm making a sample event booking app, that has event check out using stripe.
My set up is below
class Event < ActiveRecord::Base
belongs_to :user
has_many :tickets, :inverse_of => :event, dependent: :destroy
end
class Ticket < ActiveRecord::Base
belongs_to :event, :inverse_of => :tickets
end
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :ticket, :inverse_of => :bookings
has_one :sale, :inverse_of => :booking
end
class Sale < ActiveRecord::Base
belongs_to :booking, :inverse_of => :sale
belongs_to :ticket
end
class BookingsController < ApplicationController
before_filter :load_event
before_filter :load_ticket
def index
#bookings = #event.bookings
end
def new
#booking = Booking.new
end
private
def load_event
#event = Event.find(params[:event_id])
end
def load_ticket
#ticket = #event.tickets.find(params[:ticket_id])
end
def booking_params
params.require(:booking).permit(:buyer_name, :phone, :address, :order_quantity,:total_amount)
end
end
class TransactionsController < ApplicationController
before_filter :load_event
before_filter :load_booking
before_filter :load_ticket
def new
end
def pickup
#sale = Sale.find_by!(guid: params[:guid])
#booking = #sale.booking
end
def complete
#sale = Sale.find_by!(guid: params[:guid])
#booking = #sale.booking
end
if sale.save
StripeCharger.perform_async(sale.guid)
render json: { guid: sale.guid }
else
errors = sale.errors.full_messages
render json: {
error: errors.join(" ")
}, status: 400
end
end
def status
sale = Sale.find_by!(guid: params[:guid])
render json: { status: sale.state }
end
private
def load_event
#event = Event.find(params[:event_id])
end
def load_booking
#booking = #event.bookings.find(params[:booking_id])
end
def load_ticket
#ticket = #booking.ticket.find(params[:ticket_id])
end
end
#Stripe Checkout Routes
I left out a view minimal details within the models . But basically What I am trying to do is have a user enter Name, and quantity of the ticket and from submitin the booking redirect to the transaction new, in which I can carry out the sale model with Stripe Check out.
My ultimate goal of everything is to get the bookings quantity input multiplied with the ticket price to get a total amount to carry through Stripe. Do anyone have any suggestions on how to improve this break down. Of modeling a events, tickets, bookings to check out type of example. Sorry if how I'm breaking it down is noobish, I'm attempting to wrap my head around accomplishing this.
In transaction controller you don't need find on #booking.ticket
def load_ticket
#ticket = #booking.ticket.find(params[:ticket_id])
end
Since #booking has only one ticket, you just need #booking.ticket

undefined method `team_id' - Ruby on Rails

The error is undefined method 'team_id' for Player:0x007fb5f41f3838.
I am trying to edit players and I am not able to do that because of an undefined method.
My guess is it has something to do with my relations. I am learning relations between models so they may not be correct.
This is my Player Model
class Player < ActiveRecord::Base
validates_length_of :description, :maximum=>4000
has_many :descriptions, through: :fouls
has_many :fouls, as: :foul_by_id
has_many :fouls, as: :foul_on_id
belongs_to :team
end
This is my Player Controller
class PlayersController < ApplicationController
before_action :authenticate_user!
before_action :most_recent_fouls
def index
#players = Player.all
end
def show
#player = Player.find(params[:id])
end
def new
#player = Player.new
end
def create
#player = Player.new(players_params)
if #player.save
redirect_to(:action => "index")
else
render("new")
end
end
def edit
#player = Player.find(params[:id])
end
def update
#player = Player.find(params[:id])
if #player.update_attributes(players_params)
redirect_to(:action => "show", :id => #player.id)
else
render("index")
end
end
def destroy
player = Player.find(params[:id]).destroy
redirect_to(:action => "index")
end
private
def players_params
params.require(:player).permit(:name, :number, :position, :bios, :descriptions, :team_id)
end
end
Because of my gut saying that it has to do with relations, here is my Team Model
class Team < ActiveRecord::Base
has_many :players
validates :name, presence: true
end
My migration table for Player
class CreatePlayers < ActiveRecord::Migration
def change
create_table :players do |p|
p.string :name
p.string :number
p.string :position
p.string :bio
p.string :description
p.integer :team_id
p.timestamps
end
end
end
Any help is appreciated. Please explain your answer. Tell me if you need any more code to be displayed.

CanCan for employees and users

I have a Ticket model, an Employee model, and a User model.
Users and Employees can create tickets, but employees also have tickets assigned to them. So user_id refers to the creator of the ticket, and employee_id refers to the assigned employee (I am not sure if this the best way or not).
Ticket.rb
class Ticket < ActiveRecord::Base
before_save :default_values
after_commit :close_solved
after_commit :close_canceled
before_create :assign_state
attr_accessible :description, :title, :employee_department_id, :user_id, :first_name, :last_name , :email, :state_id, :employee_id, :ticket_state, :assign_state
belongs_to :employee_department
belongs_to :user
belongs_to :state
belongs_to :employee
has_many :replies
def default_values
self.state_id = 3 if self.state_id.nil?
end
def to_label
ticket_state.to_s
end
def close_solved
if self.ticket_state == "solved"
self.update_column(:ticket_state, "closed (solved)")
self.save!
end
end
def close_canceled
if self.ticket_state == "canceled"
self.update_column(:ticket_state, "closed (canceled)")
self.save!
end
end
def assign_state
if self.employee_id.nil?
self.assign_state = "un-assigned"
else
self.assign_state = "assigned"
end
end
Ticket.all.each do |ticket|
if ticket.ticket_state.blank?
ticket.ticket_state = 'open'
end
ticket.save
end
end
Employee.rb
class Employee < ActiveRecord::Base
# attr_accessible :title, :body
after_create :add_to_users
attr_accessible :employee_number, :joining_date, :first_name, :middle_name, :last_name,
:gender, :job_title, :employee_department_id, :qualification, :experience_detail,
:experience_year, :experience_month, :status_description, :date_of_birth, :marital_status,
:children_count, :father_name, :mother_name, :husband_name, :blood_group, :nationality_id,
:home_address_line1, :home_address_line2, :home_city, :home_state, :home_pin_code,
:office_address_line1, :office_address_line2, :office_city, :office_state, :office_pin_code,
:office_phone1, :office_phone2, :mobile_phone, :home_phone, :email, :fax, :user_id, :school_id,
:employee_category_id, :employee_position_id, :reporting_manager_id, :employee_grade_id,
:office_country_id, :home_country_id
belongs_to :employee_department
belongs_to :employee_category
belongs_to :employee_position
belongs_to :employee_grade
belongs_to :nationality, class_name: 'Country'
belongs_to :reporting_manager, class_name: "Employee"
belongs_to :school
belongs_to :user
has_many :tickets
def add_to_users
new_user = User.new
new_user.user_name = self.first_name
new_user.first_name = self.first_name
new_user.last_name = self.last_name
new_user.email = self.email
new_user.password = "123456"
new_user.password_confirmation = "123456"
new_user.user_type_id = 2
new_user.save
t = Employee.find(self.id)
t.user_id = new_user.id
t.save
end
def to_label
full_name = first_name + " " + last_name
end
def full_name
full_name = first_name + " " + last_name
end
end
User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :validatable,:confirmable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable,
:trackable, :lockable, :timeoutable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :user_name, :first_name, :last_name, :password, :password_confirmation, :remember_me,
:role_ids, :current_password, :user_type
attr_accessor :current_password
# attr_accessible :title, :body
has_many :assignments
has_many :roles, :through => :assignments
has_many :articles
has_many :comments
has_many :students
has_many :guardians
has_many :employees
has_many :tickets
has_many :permissions
accepts_nested_attributes_for :tickets
def has_role?(role_sym)
roles.any? { |r| r.role_name.underscore.to_sym == role_sym }
end
end
Ability.rb
class Ability
include CanCan::Ability
def initialize(user)
#user = user || User.new
if user.has_role? :administrator
can :manage, :all
end
if user.has_role? :admission_manager
can :manage, Student
end
if user.has_role? :news_manager
can :manage, Article
end
if user.has_role? :ticket_manager
can :manage, Ticket
end
if user.has_role? :student_viewer
can :read, Student
end
if user.has_role? :news_viewer
can :read, Article
end
if user.has_role? :ticket_viewer #he should be able to create tickets and see what he has created.
can :create, Ticket
can :read, Ticket
end
end
end
Ticket_controller.rb
class TicketsController < ApplicationController
load_and_authorize_resource
def index
#tickets = Ticket.all
#tickets_grid = initialize_grid(Ticket, :include => [{:user => :user_type}, :employee_department, :state])
end
def show
#ticket = Ticket.find(params[:id])
#reply = #ticket.replies.build # this for comments on ticket
#state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal )
end
def new
#ticket = Ticket.new
end
def create
#ticket = Ticket.new(params[:ticket])
if #ticket.save
flash[:notice] = 'Support ticket request created.'
redirect_to #ticket
else
flash[:error] = 'An error occurred please try again!'
redirect_to '/dashboard'
end
end
def edit
#ticket = Ticket.find(params[:id])
end
def update
#ticket = Ticket.find(params[:id])
if #ticket.update_attributes(params[:ticket])
flash[:notice] = 'Successfuly updated.'
redirect_to tickets_path
else
flash[:error] = 'An error occurred please try again!'
render #ticket
end
end
end
I need to allow Employees to be able to manage their assigned tickets, and I need the creator of the ticket to see only the tickets he created.
How can I do this using CanCan? I'm open to other suggestions, if it cannot be done with CanCan.
For users to be able to read the tickets they've created, you just need to add a condition on the ability (see below). You can use the same condition on the :create ability and cancan will pre-fill those attributes for you when it builds a new object for the #new or #create actions.
# app/models/ticket.rb
class Ticket < ActiveRecord::Base
# <snip>
belongs_to :user
belongs_to :employee
# <snip>
end
# app/models/user.rb
class User < ActiveRecord::Base
has_one :employee
end
# app/models/ability.rb
class Ability
# <snip>
if user.has_role? :ticket_viewer
can :create, Ticket
can :read, Ticket, :user_id => user.id
end
if user.employee # && any other necessary conditions
can :create, Ticket
can :read, Ticket, :employee_id => user.employee.id
end
end
# app/controllers/tickets_controller.rb
controller TicketsController < ApplicationController
load_and_authorize_resource
def index
# #tickets = Ticket.accessible_by(current_ability) # cancan's
# load_and_authorize resource will take care of loading ticket(s) for
# all controller actions, so I've commented them out
#tickets_grid = initialize_grid(#tickets, :include => [{:user => :user_type}, :employee_department, :state])
end
def show
# #ticket = Ticket.find(params[:id])
#reply = #ticket.replies.build # this for comments on ticket
#state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal )
end
def new
# #ticket = Ticket.new
end
def create
# #ticket = Ticket.new(params[:ticket])
if #ticket.save
flash[:notice] = 'Support ticket request created.'
redirect_to #ticket
else
flash[:error] = 'An error occurred please try again!'
redirect_to '/dashboard'
end
end
def edit
# #ticket = Ticket.find(params[:id])
end
def update
# #ticket = Ticket.find(params[:id])
if #ticket.update_attributes(params[:ticket])
flash[:notice] = 'Successfuly updated.'
redirect_to tickets_path
else
flash[:error] = 'An error occurred please try again!'
render #ticket
end
end
end
This is fairly simple to achieve using CanCan. Here's a quick example using a modified subsection of the ability file you included:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# Full access if you're the assigned employee
if user.has_role? :support_manager
can :manage, Ticket do |ticket|
ticket.try(employee) == user
end
end
# Read access only if you created the ticket
can :read, Ticket do |ticket|
ticket.try(user) == user
end
end
end
you will see all the tickets because in index action inside your controller you call:
#tickets = Ticket.all
you can try this:
#tickets = Ticket.accessible_by(current_ability)
by using this method current_user will see all tickets that current_user has access to
Update
you can define specific access in the accessible_method
#tickets = Ticket.accessible_by(current_ability, :manage)
the rest is how you define the access
https://github.com/ryanb/cancan/wiki/Fetching-Records
Example on define the access:
if user.has_role? :ticket_manager
can :manage, Ticket, employee: {:user_id => user.id}
end

Resources