Cannot map Employee back to User ID correctly - ruby-on-rails

My problem is: I have a User model , Employee , Student, Parent. I don't know how to map each of Employee , Student, Parent back to User ID correctly. because in the current state for example I have differentiating by a normal user and an employee (since the employee is a user as well ) , How can I do so ? For example I will paste Employee and User and Ticket so you can help me to map it correctly because in my system Ticket model is not dealing with the Employee as a User . please I am stuck on this two days ago :(
In those models , user_id in the ticket model is refering to creator of tickets and employee id is refering to assigned employee and thats the error i need to map Employee back to User ID correctly
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_id
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
belongs_to :user_type
accepts_nested_attributes_for :tickets
def has_role?(role_sym)
roles.any? { |r| r.role_name.underscore.to_sym == role_sym }
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
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

Related

How to combine information from two tables when creating a JSON on Ruby on Rails?

What is the best approach to combine information from two different tables on Ruby on Rails, when building a JSON for Web Services purpose?
I want to combine my list of clients with a tag that is taken from another table than users table.
Here is how I proceed from the controller
def clients
#orders = #bar.orders
#users = User.where(id: #orders.pluck(:user_id).uniq).all
#tags = UserTag.where(bar: #bar, user_id: #orders.pluck(:user_id).uniq).all
end
The view is built this way
json.user_tags do
json.array!(#tags) do |user_tag|
json.extract! user_tag, :id, :bar_id, :user_id, :tag
end
end
json.users do
json.array!(#users) do |user|
json.extract! user, :id, :first_name, :last_name, :email, :facebook_id, :context, :created_at, :updated_at, :company, :phone, :birthdate, :stripe_customer_id, :bar_id, :role
end
end
The JSON generated with this code looks like this
I would like to integrate the tag field directly in users array, next to other users information such as on this illustration
The UserTag model is built like that
class UserTag < ActiveRecord::Base
belongs_to :user, :counter_cache => true
belongs_to :bar
validates_uniqueness_of :bar_id, :user_id, :scope => :bar_id
acts_as_paranoid without_default_scope: true
def self.default_scope
with_deleted
end
def api_error_message
errors.full_messages.join("\n")
end
end
And User model:
class User < ActiveRecord::Base
has_many :access_tokens, dependent: :destroy
belongs_to :club
belongs_to :bar
enum role: [:user, :club_owner, :waiter, :admin]
has_many :club_comments
has_many :club_subscriptions
has_many :artist_subscriptions
has_many :artist_votes
has_many :payments
has_many :carts
has_many :user_entrances
has_many :bookings, through: :user_entrances
has_many :booking_events, through: :user_entrances
has_many :cart_item_consumptions
has_many :clientlist_elements
has_secure_password
has_one :address, as: :addressable
accepts_nested_attributes_for :address
validates :password, length: {minimum: 8}, if: :validate_password?
validates :password_confirmation, presence: true, if: :validate_password?
validates :email, presence: true, if: :user_context_email
validates :email, email: true, if: :user_context_email
validates :email, :facebook_id, uniqueness: true, :allow_blank => true, :allow_nil => true
validates :first_name, presence: true
validates :last_name, presence: true
reverse_geocoded_by :latitude, :longitude
after_create :create_access_token
after_save :update_vote_position_if_needed
def validate_password?
password.present? || password_confirmation.present?
end
def name
"#{first_name.capitalize} #{last_name.capitalize}"
end
def create_access_token
AccessToken.create(user: self)
end
def user_context_email
context == 0
end
def user_context_fb
context == 1
end
def update_vote_position_if_needed
if self.latitude_changed? || self.longitude_changed?
self.delay.update_vote_position
end
end
def update_vote_position
self.artist_votes.each do |vote|
vote.latitude = self.latitude
vote.longitude = self.longitude
vote.save
end
end
def stripe_description
"#{first_name} #{last_name} - #{email}"
end
def stripe_customer_metadata
{"User_id" => self.id, "Firstname" => self.first_name, "Lastname" => self.last_name, "Email" => self.email, "Phone" => self.phone}
end
def api_error_message
errors.full_messages.join("\n")
end
end
EDIT
I tried the #krishnar solution, here is how the JSON looks like now
The users are duplicated and only users with tag appear (we need to display all users even those without tags)
Modify user model to have association:
class User < ActiveRecord::Base
# define user to user_tags association
has_many :user_tags
end
Join users table with user_tags and select user_tags id as tag to use in json file:
def clients
#orders = #bar.orders
#users = User.where(id: #orders.pluck(:user_id).uniq).joins("left join user_tags on users.id=user_tags.user_id and user_tags.bar_id='#{#bar.id}'").select("users.*","user_tags.id as tag")
#tags = UserTag.where(bar: #bar, user_id: #orders.pluck(:user_id).uniq).all
end
Now you can access tag in #users array:
json.users do
json.array!(#users) do |user|
json.extract! user, :id, :first_name, :last_name, :email, :facebook_id, :context, :created_at, :updated_at, :company, :phone, :birthdate, :stripe_customer_id, :bar_id, :role, :tag
end
end

Active_scaffold add to list associated table column

class Agency < ActiveRecord::Base
has_many :events
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :name, :email, :phone, :address, :city, :state, :zip,
:notes, :is_admin, :password, :password_confirmation, :remember_me
end
class Event < ActiveRecord::Base
belongs_to :agency
has_many :consumers
end
class Consumer < ActiveRecord::Base
belongs_to :event
end
In consumers_controller I am trying to include some field from agency
active_scaffold :consumer do |conf|
list.columns = [
:agency, :event
]
end
There are such associations Agency -> Event -> Consumer. And there is no association between agency and consumer, only through event.
but it causes an error.
How Can I include to list a any field form agency table?
According to the wiki, I think what you want is this:
active_scaffold :consumer do |conf|
conf.columns = [:agency, :event]
end
Also, make sure a consumer has an agency association or column.
Solution was a quite simple but most likely inefficient.
I have added a method to Consumer model:
class Consumer < ActiveRecord::Base
...
def agency_name
self.event.agency[:name]
end
end
Then I have added a virtual column to list:
list.columns = [
:agency_name, :event, ... ]
That's all.

ActiveRecord - Find next user in group model

I've four user models: Zone, Product, User, Group
I want to choose what Users can sell a Product in a Zone, this is what Group does, with a many to many relation to User and a foreign key to one Product and one Zone. So I have one group per pair Zone/Product. I will also need to set custom attributes on that many to many relation so I used has_many :through Sell (I was unable to find a better name to describe the relation between Group and User).
So I ended up having 5 models: Zone, Product, User, Group, Sell.
It works fine, but now I'd need to select the next user available in a Group.
I was thinking to exploit Sell.id to find the user assigned to the same group with an higher id, if not present choose the first one again (this allows me to create a ring chain).
It would be useful to have a Group.next_user method.
Unfortunatly I can't figure out how to do this, I'd need help to find the next user available in the group (or the 1st one if there are no more users).
Follows the code for models all the models:
################
# models/group.rb
################
class Group < ActiveRecord::Base
has_many :sells
has_many :users, :through => :sells
belongs_to :zone
belongs_to :product
attr_accessible :priority, :product_id, :user_ids, :zone_id
end
################
# models/zone.rb
################
class Zone < ActiveRecord::Base
belongs_to :location
has_many :cities
has_many :groups
attr_accessible :name, :location_id
validates :location, :presence => true
end
################
# models/user.rb
################
class User < ActiveRecord::Base
after_create :create_calendar
before_destroy :destroy_calendar
belongs_to :location
belongs_to :mall
has_one :event_calendar
has_many :sells
has_many :groups, :through => :sells
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable, :registerable,
# :recoverable, :rememberable,
devise :database_authenticatable, :trackable,
:validatable, :authentication_keys => [:username]
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :password, :password_confirmation, :remember_me, :name,
:surname, :role, :location_id
# attr_accessible :title, :body
ROLES = %w[Admin Agente Hostess HostessAdmin]
validates_uniqueness_of :username, :case_sensitive => false
validates :username, :presence => true
validates_presence_of :role, :name, :surname, :location_id
validates :location, :presence => true
validates :role, :inclusion => { :in => ROLES, :message => "%{value} non è un ruolo valido." }
def display_name
"#{self.name} #{self.surname}"
end
def has_role?(role)
# convert the role string to a sybmol
self.role.downcase.gsub(/\s+/, "_").to_sym == role
end
private
def create_calendar
if self.has_role? :agente
calendar = EventCalendar.new({:user_id => self.id})
calendar.save()
end
end
def destroy_calendar
if self.has_role? :agente
calendar = EventCalendar.find_by_user_id(self.id)
calendar.destroy()
end
end
def email_required?
false
end
def email_changed?
false
end
end
################
# models/product.rb
################
class Product < ActiveRecord::Base
after_create :create_groups
before_destroy :destroy_groups
attr_accessible :name
def create_groups
for zone in Zone.all
group = Group.new({:zone_id => zone.id, :product_id => self.id})
group.save()
end
end
def destroy_groups
for zone in Zone.all
group = Group.find_by_product_id(self.id)
group.destroy
end
end
end
################
# models/sell.rb
################
class Sell < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Can you give me some help to get this done? Thanks!
If I get this right then addd this to your User model
scope :next, lambda { |p| {:conditions => ["id > ?", p.id], :limit => 1, :order => "id"} }
and this to your group model
def self.next_user
return User.first if Group.users.blank?
next_user = User.next(Group.users.last).first
return next_user || Group.users.first
end
This should do the trick. I didn't write test for this so you should test it :)

Nested Form Update in Rails 3 sets foreign key as NULL

I am trying to update a user record using a formtastic nested form. Its structure is as ollows
User
Admin
Address
When I send the form to update details, while updating the address or admin record, the user_id(foreign key) gets set to NULL. This is the data that gets sent and it seems to be ok.
Parameters: {
"utf8"=>"✓", "authenticity_token"=>"some token",
"user"=>{
"id"=>"16",
"first_name"=>"User",
"last_name"=>"Name",
"email"=>"username#gmail.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]",
"address_attributes"=>{
"main_phone"=>"131231233",
"address1"=>"Address 1 Line",
"address2"=>"Address 2 Line",
"city"=>"Lansing",
"state"=>"Michigan",
"zip"=>"48823",
"user_id"=>"16"
},
"admin_attributes"=>{
"company_id"=>"2",
"user_id"=>"16"
},
"roles_mask"=>"1",
"user_id"=>"16"
},
"commit"=>"Update User Roles",
"company_id"=>"2",
"id"=>"16"
}
User Model
class User < ActiveRecord::Base
has_one :address, :dependent => :destroy, :inverse_of => :user
has_one :admin, :dependent => :destroy, :inverse_of => :user
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :roles_mask, :terms_of_use,:id
attr_accessible :owner_attributes, :admin_attributes, :address_attributes, :client_attributes
accepts_nested_attributes_for :owner, :admin, :client, :address
end
Admin Model
class Admin < ActiveRecord::Base
belongs_to :company
belongs_to :user, :inverse_of => :admin
attr_accessible :company_id, :user_id
end
*Address Model
class Address < ActiveRecord::Base
belongs_to :user, :inverse_of => :address
attr_accessible :address1, :user_id, :address2, :city, :state, :zip, :main_phone, :cell_phone
end
Could you please help me with this. Thanks.
UPDATED with the model details. I removed the validation to keep it short.
Try to correct
accepts_nested_attributes_for :owner, :admin, :client, :address
in your User model with
accepts_nested_attributes_for :owner, :client
accepts_nested_attributes_for :admin, :address, :update_only => true

Has a relationship through four models?

I'm having trouble setting up this association between my models.
A User has many Accommodations, and Accommodations have one User.
Accommodations have many Notifications, and Notifications have one Accommodation.
Requests have many Notifications.
How can I make it so that I can get all of the Requests for a given User ( that is, User -> Accommodations (each) -> Notification -> Request)?
Update:
Here's my current controller file:
class PanelController < ApplicationController
before_filter :login_required
def index
#accommodations = current_user.accommodations.all
#requests = Array.new
#accommodations.each do |a|
a.notifications.each do |n|
#requests << Request.where('id' => n.request_id)
end
end
end
end
And models:
models/user.rb
class User < ActiveRecord::Base
[snip]
has_many :accommodations
has_many :notifications,
:through => :accommodations
end
models/accommodation.rb
class Accommodation < ActiveRecord::Base
validates_presence_of :title, :description, :thing, :location, :spaces, :price, :photo
attr_accessible :photo_attributes, :title, :description, :thing, :location, :spaces, :price
has_one :photo
has_many :notifications
belongs_to :user
accepts_nested_attributes_for :photo, :allow_destroy => true
end
models/notification.rb
class Notification < ActiveRecord::Base
attr_accessible :accommodation_id, :request_id
has_one :request
belongs_to :accommodation
end
models/request.rb
class Request < ActiveRecord::Base
belongs_to :notifications
attr_accessible :firstname, :lastname, :email, :phone, :datestart, :dateend, :adults, :children, :location, :status
validates_presence_of :firstname, :lastname, :email, :phone, :datestart, :dateend, :children, :adults, :location
end
Something like this should work:
#reqs = []
#user.accommodations.all.each do |a|
#reqs << a.notification.request
end
Assuming this is correct:
class User
has_many :accommodations
end
class Accommodation
belongs_to :user
has_many :notifications
end
class Notification
belongs_to :accomodation
belongs_to :request
end
class Request
has_many :notifications
end
Using has_many :through will not work for multiple models, as seen here: Ruby-on-Rails: Multiple has_many :through possible?
But you can do something like this in your user model:
class User
has_many :accommodations
has_many :notifications,
:through => :accommodations
def requests
self.notifications.all.collect{|n| n.request }
end
end

Resources