I have campaign, campaign_commissions, applicant and applicant_commissions modals.
campaign_commissions are all commissions available for a campaign and applicant_commissions are the applicants instance of those commissions.
When I delete an applicant, rails_admin also wants to delete both campaign_commissions and applicant_commissions. I only wish for applicant_commissions to be destroyed.
How can I specify this to happen?
My Models:
applicant.rb
class Applicant < ActiveRecord::Base
enum hired: [:pending, :declined, :awaiting_post, :accepted]
attr_accessor :post_url
belongs_to :post
belongs_to :campaign
belongs_to :site
has_many :applicant_commissions
accepts_nested_attributes_for :applicant_commissions
has_many :campaign_commissions, through: :applicant_commissions
scope :accepted, -> { where('hired == ?', 3) }
scope :declined, -> { where('hired < ?', 1) }
scope :pending, -> { where('hired < ?', 0) }
scope :awaiting_post, -> { where('hired < ?', 2) }
validates :campaign_id, :presence => true
#validates :site_id, :presence => true
validates :applicant_commissions, :presence => true
validates :campaign_id, uniqueness: { scope: :site_id,
message: "We already have an application from you" }
applicant_commission.rb
class ApplicantCommission < ActiveRecord::Base
include ActionView::Helpers::NumberHelper
belongs_to :applicant
belongs_to :campaign_commission
has_many :invoice_parts
#delegate :user, to: applicant
end
campaign_commission.rb
class CampaignCommission < ActiveRecord::Base
belongs_to :campaign
belongs_to :commission
has_many :applicant_commissions
has_many :applicants, through: :applicant_commissions
end
campaign.rb (not involved in the issue, but added for context)
class Campaign < ActiveRecord::Base
has_attached_file :image, :styles => { :default => "500x500>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
belongs_to :programme
belongs_to :user
has_many :applicants
has_many :campaign_commissions
has_many :commissions, through: :campaign_commissions
has_many :images, as: :imageable
scope :front, -> { limit(4) }
end
applicant_commissions reaches through to the campaign commissions via this relationship.
has_many :campaign_commissions, through: :applicant_commissions
I would suggest this to sever the tie to solve the problem you presented.
has_many :campaign_commissions
And, I didn't see this in your sample model, but for answer completeness I'll include it here. If you don't include the destroy attribute, the dependent record (or association dependent) will not be deleted.
has_many :applicant_commissions, :dependent => :destroy
I don't think you can have the has many through relationship both ways, as live during application run but suspend the relationship when you want to delete the parent record. But maybe someone will come along with an answer and a way to do that.
Related
Given the following models:
Business
class Business < ActiveRecord::Base
## OWNERS / EMPLOYEES
has_many :business_users, as: :business, dependent: :destroy
has_many :users, through: :business_users
accepts_nested_attributes_for :business_users, allow_destroy: true, reject_if: lambda { |a| a[:user_id].blank? || a[:role].blank? }
end
BusinessUser
class BusinessUser < ActiveRecord::Base
belongs_to :business, polymorphic: true
belongs_to :user
enum role: {:owner => 0, :employee => 1, :admin => 2}
validates_presence_of :user
validates :user, uniqueness: { scope: :business, message: "Each user can only have one role" }
end
User
class User < ActiveRecord::Base
has_many :business_users
has_many :businesses, through: :business_users, source_type: Business, source: :business
end
How can i make sure that each business has at least one business_user with role :owner?
Given is a User Model who has_many Projects.
each Projects belongs_to a User
joined by a Assigned_projects Model
each Project has_many Expenses which belongs to a Project and a User
User Model:
class User < ActiveRecord::Base
has_many :assigned_projects
has_many :projects, :through => :assigned_projects
has_many :created_projects, :class_name => "Project", :foreign_key => :creator_id
end
Project Model:
class Project < ActiveRecord::Base
belongs_to :user
has_many :assigned_projects
has_many :users, :through => :assigned_projects
belongs_to :creator, :class_name => "User", :foreign_key => :creator_id
has_many :expenses
end
join Model:
class AssignedProject < ActiveRecord::Base
attr_accessible :project_id, :user_id, :position, :project
belongs_to :user, class_name: "User"
belongs_to :project, class_name: "Project"
validates :user_id, presence: true
validates :project_id, presence: true
end
Expenses Model:
class Expense < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
Sum all Expenses of a project is easy:
#current_project.expenses.sum(:amount)
I want to list the sum of all Expenses each User added.
The Question is how to sum all Expenses for each user who is assigned to the Project.
I'am looking for something like:
#current_user.#current_project.expenses.sum(:amount)
I assume you are trying to do the following. If not, please explain your question a bit more.
#current_project.expenses.where(user_id: #current_user.id).sum(:amount)
i'm using sqlit3 for local and Postgre for heroku.
Everything works fine until i upload my files to heroku. Here is my model.
class User < ActiveRecord::Base
belongs_to :unit
has_friends
end
class Unit < ActiveRecord::Base
attr_accessible :unit, :floor
has_many :users
belongs_to :block
end
class Block < ActiveRecord::Base
attr_accessible :block, :units_attributes
has_many :units, :dependent => :destroy
accepts_nested_attributes_for :units, allow_destroy: true
belongs_to :postalcode
end
class Postalcode < ActiveRecord::Base
attr_accessible :postalcode, :blocks_attributes
has_many :blocks, :dependent => :destroy
accepts_nested_attributes_for :blocks, allow_destroy: true
belongs_to :neighbourhood
end
class Neighbourhood < ActiveRecord::Base
attr_accessible :name, :streetname, :postalcodes_attributes
has_many :postalcodes, :dependent => :destroy
has_many :blocks, :through => :postalcodes
has_many :units, :through => :blocks
has_many :users, :through => :units
accepts_nested_attributes_for :postalcodes, allow_destroy: true
validates :name, :presence => true
validates :streetname, :presence => true
end
i troubleshooted and found that the problem is with this method in the controller.
#neighbours = current_user.unit.block.postalcode.neighbourhood.users
Although #neighbours = current_user.unit.block.postalcode.neighbourhood works perfectly fine.
Please help, i'm desperate, i have tried googling for it one whole day.
Check out this answer to a similar issue
It is quite likely the error is coming up from WHERE "postalcodes"."neighbourhood_id" = 1 which indicates that neighbourhood_id in postalcodes table is created as a String, instead of an integer.
Follow the steps mentioned in the answer accordingly, and change it to an Integer.
i have the following models
class Airplane < ActiveRecord::Base
has_many :airtags
has_many :pictures, :through => :airtags
end
class Airtag < ActiveRecord::Base
attr_accessible :airable_type, :airable_id, :airplane_id
belongs_to :airplane
belongs_to :airable, :polymorphic => true
end
class Picture < ActiveRecord::Base
belongs_to :picturable, :polymorphic => true
has_many :airtags, :as => :airable, :dependent => :destroy
has_many :airplanes, :through => :airtags
end
in my airplane show, i want to list all pictures, ordered by their name.
#airplane.pictures.order(:name)
I have users and issues joined by a votership model. Users can vote on issues. They can either vote up or down (which is recorded in the votership model). First, I want to be able to prevent users from casting multiple votes in one direction. Second, I want to allow users to cast the opposite vote. So, if they voted up, they should still be able to vote down which will replace the up vote. Users should never be able to vote on an issue twice. Here are my files:
class Issue < ActiveRecord::Base
has_many :associations, :dependent => :destroy
has_many :users, :through => :associations
has_many :voterships, :dependent => :destroy
has_many :users, :through => :voterships
belongs_to :app
STATUS = ['Open', 'Closed']
validates :subject, :presence => true,
:length => { :maximum => 50 }
validates :description, :presence => true,
:length => { :maximum => 200 }
validates :type, :presence => true
validates :status, :presence => true
def cast_vote_up!(user_id, direction)
voterships.create!(:issue_id => self.id, :user_id => user_id,
:direction => direction)
end
end
class Votership < ActiveRecord::Base
belongs_to :user
belongs_to :issue
end
class VotershipsController < ApplicationController
def create
session[:return_to] = request.referrer
#issue = Issue.find(params[:votership][:issue_id])
#issue.cast_vote_up!(current_user.id, "up")
redirect_to session[:return_to]
end
end
class User < ActiveRecord::Base
authenticates_with_sorcery!
attr_accessible :email, :password, :password_confirmation
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
has_many :associations, :dependent => :destroy
has_many :issues, :through => :associations
has_many :voterships, :dependent => :destroy
has_many :issues, :through => :voterships
end
You would put the uniqueness constraint on the Votership model. You don't need to put validations on the association itself.
class Votership < ActiveRecord::Base
belongs_to :user
belongs_to :issue
validates :issue_id, :uniqueness => {:scope=>:user_id}
end
This means a user can only have a single vote on a given issue (up or down).
Relationship models:
class Person
has_many :accounts
has_many :computers, through: :accounts
end
class Account
belongs_to :person
belongs_to :computer
scope :administrators, -> { where(role: 'administrator') }
end
class Computer
has_many :accounts
has_many :people, through: :accounts
end
This is how it is called
person.accounts.administrators.map(&:computer)
We can do this better using ActiveRecord::SpawnMethods#merge!
person.computers.merge(Account.administrators)
Ref: https://coderwall.com/p/9xk6ra/rails-filter-using-join-model-on-has_many-through