Rails dependent destroy not working - ruby-on-rails

I have User and Organization model. User has_many :organizations and Organization has_many :users.
When I want to destroy user from db using #user.destroy I get error Key (id)=(3) is still referenced from table "organizations".
Here is my User and Organization models:
Organization.rb
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, :use => :slugged
has_many :members, :dependent => :destroy
has_many :users, :through => :members, :dependent => :destroy
has_many :moderators, -> { where :members => { :role => 1 } }, :through => :members, :source => :user
has_many :admins, -> { where :members => { :role => 2 } }, :through => :members, :source => :user
has_many :campains, :dependent => :destroy
has_many :statuses, :as => :statusable
has_many :activities
has_many :world_members
has_many :teams
accepts_nested_attributes_for :members, :users
User.rb
class User < ApplicationRecord
extend FriendlyId
friendly_id :full_name, :use => :slugged
acts_as_voter
enum role: [:user, :moderator, :organization, :admin]
has_many :members, :class_name => "Member", :foreign_key => "user_id", :dependent => :destroy
has_many :organizations, :through => :members, :dependent => :destroy
has_many :conversations, :foreign_key => :sender_id
has_many :admin_organizations, ->{ where(members: {role: 2}) }, :through => :members, source: :organization
has_many :moderate_organizations, ->{ where(members: {role: 1}) }, :through => :members, source: :organization
has_many :member_organizations, ->{ where(members: {role: 0}) }, :through => :members, source: :organization
accepts_nested_attributes_for :members, :organizations
Member.rb
class Member < ApplicationRecord
enum role: [:member, :moderator, :admin]
belongs_to :user
belongs_to :organization

You should not have dependent_destroy for :organizations or :users, just for :members.
You do not have direct relation from organization to user, nor from user to organization.
class User < ActiveRecord::Base
has_many :members, dependent: :destroy
has_many :organizations, through: :members
end
class Organization < ActiveRecord::Base
has_many :members, dependent: :destroy
has_many :users, through: :members
end
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
As you do not want to delete all users for example from an organization, just there reference to the organization and vice verse if you delete user, you do not want to delete all organizations on which user was connected to, just the reference

Related

Rails select from database table by multiple join throug other table

I have model Category (categories of Images)
class Category < ApplicationRecord
has_many :images, foreign_key: 'category_id', dependent: :destroy
has_many :subscriptions, foreign_key: "category_id", dependent: :destroy
has_many :subscribed_users, :through => :subscriptions, :source => :user
end
Model Category has many subscribtions and subscribed users
class Subscription < ApplicationRecord
belongs_to :user
belongs_to :category
validates :user_id, presence: true
validates :category_id, presence: true
end
class User < ApplicationRecord
has_many :images, foreign_key: 'user_id', dependent: :destroy
has_many :categories, foreign_key: 'user_id', dependent: :destroy
has_many :likes, foreign_key: "user_id", dependent: :destroy
has_many :liked_images, :through => :likes, :source => :images
has_many :comments, foreign_key: "user_id", dependent: :destroy
has_many :commented_images, :through => :comments, :source => :images
has_many :subscriptions, foreign_key: 'user_id', dependent: :destroy
has_many :subscribed_categories, :through => :subscriptions, :source => :categories
end
Also I have model Image
class Image < ApplicationRecord
belongs_to :user
belongs_to :category
has_many :likes, foreign_key: "image_id", dependent: :destroy
has_many :liking_users, :through => :likes, :source => :user
has_many :comments, foreign_key: "image_id", dependent: :destroy
has_many :commenting_users, :through => :comments, :source => :user
end
which has many likes and comments (comments and likes to Image, not to categories of image)
class Like < ApplicationRecord
belongs_to :user
belongs_to :image
validates :user_id, presence: true
validates :image_id, presence: true
end
class Comment < ApplicationRecord
belongs_to :user
belongs_to :image
validates :user_id, presence: true
validates :image_id, presence: true
end
I need to select from database 5 most popular categories.
The most popular category is category which has highest count of likes, comments and images at the same time.
I made one query, which select all images, that has the highest count of likes and comments:
#top_images = Image.left_outer_joins(:likes).distinct.select('images.*, COUNT(likes.*) AS likes_count').left_outer_joins(:comments).distinct.select('images.*, COUNT(comments.*) AS comments_count').group(
'images.id').order("likes_count DESC").order("comments_count DESC")
Also I make query which select categories, which has more images:
#top_categories_img_count = Category.left_outer_joins(:images).distinct.select('categories.*, COUNT(images.*) AS images_count').group(
'categories.id').order("images_count DESC")
But I have no idea how to select all categories which have highest count of images, likes and comments

uninitialized constant User::relationship using #blog.user.followers.build

The below code works without error:
= form_for #blog.comments.build, :remote => true do |f|
However the below results in the error "uninitialized constant User::relationship":
= form_for #blog.user.followers.build do |f|
User model is declared as below:
class User < ActiveRecord::Base
has_many :blogs
has_many :comments
has_many :relationships, :foreign_key => "follower_id", :dependent => :destroy
has_many :reverse_relationships, :foreign_key => "followed_id",
:class_name => "relationship",
:dependent => :destroy
has_many :following, :through => :relationships, :source => :followed
has_many :followers, :through => :reverse_relationships, :source => :follower
end
Why does the first example work but not hte second?
EDIT:
Blog model:
class Blog < ActiveRecord::Base
belongs_to :user
has_many :comments
end
Relationship model:
class Relationship < ActiveRecord::Base
attr_accessible :followed_id
belongs_to :follower, :class_name => "User"
belongs_to :followed, :class_name => "User"
validates :follower_id, :presence => true
validates :followed_id, :presence => true
validate :validate_followers
def validate_followers
errors.add(:follower_id, "You cannot follow yourself") if follower_id == followed_id
end
end
If you change the :class_name option on reverse relationships to:
:class_name => 'Relationship'
do you still get the problem? It should be the correct case for a class name I believe.

multiple belongs_to relationship to three model

The situation is this way..
class Organization < ActiveRecord::Base
has_many :role_memberships
has_many :roles
has_many :users, :through => :role_memberships, :uniq => true
end
class User
has_many :role_memberships
has_many :organizations, :through => :role_memberships, :uniq => true
has_many :roles, :through => :role_memberships, :uniq => true
end
class RoleMembership < ActiveRecord::Base
belongs_to :organization
belongs_to :role
belongs_to :user
end
class Role < ActiveRecord::Base
belongs_to :organization
has_many :role_memberships
has_many :users, :through => :role_memberships, :uniq => true
end
The QUESTION is how do I populate all the three foreign-keys in rolemembership table..when I do org.users.push(u) this create a record but role_id is left out...
In this case I will probably create RoleMembership object itself, like this:
RoleMembership.create(:organization_id => org.id, :role_id => role.id, :user_id => user.id)

Rails Relationship Help

I have simplified my design to make this question more clear. (Design of models below)
What I am trying to do is from a CourseEnrollment get all the PatientCourseSteps for that enrollment only (An enrollment consists of a patient and a course).
Here is what I have tried:
#Gives me ALL the patient course steps regardless of the course
course_enrollment.patient.patient_course_steps
#Gives me ALL the patient course steps regardless of the patient
course_enrollment.course.patient_course_steps
Below is the models that are necessary
class CourseEnrollment < ActiveRecord::Base
belongs_to :patient
belongs_to :course
end
class Course < ActiveRecord::Base
has_many :course_steps, :dependent => :destroy
has_many :steps, :through => :course_steps
has_many :course_enrollments, :dependent => :destroy
has_many :patients, :through =>:course_enrollments
has_many :patient_course_steps, :dependent => :destroy
end
class Patient < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
has_many :enrollments, :dependent => :destroy
has_many :clients, :through => :enrollments
has_many :course_enrollments, :dependent => :destroy
has_many :courses, :through => :course_enrollments
has_many :patient_course_steps, :dependent => :destroy
end
class Step < ActiveRecord::Base
belongs_to :step_type
belongs_to :client
has_one :step_quiz, :dependent => :destroy
has_one :step_survey, :dependent => :destroy
has_one :step_text, :dependent => :destroy
has_one :step_download, :dependent => :destroy
has_one :step_video, :dependent => :destroy
has_one :step_presentation, :dependent => :destroy
has_many :course_steps, :dependent => :destroy
has_many :courses, :through => :course_steps
has_many :patient_course_steps, :dependent => :destroy
end
class PatientCourseStep < ActiveRecord::Base
belongs_to :patient
belongs_to :course
belongs_to :step
end
What I ended up doing was adding a method to CourseEnrollment named patient_course_steps which queries for what I need.
def patient_course_steps
PatientCourseStep.where(:patient_id => self.patient_id, :course_id => self.course_id)
end

Nested Has Many Through Plugin and Named Scopes

I have a User Model(:name, :password, :email), and Event model(:name, :etc) and Interest model (:name) [>all singular<]
Then I created two join tables -> UsersInterests and EventsInterests; each not containing a primary key and only comprised of the user_id/interest_id and event_id/interest_id respectively. [>plural<]
My Models Use the Nested Has Many Through Plugin
user.rb => has_many :users_interests
has_many :interests, :through => :users_interests
has_many :events_interests, :through => :interests
has_many :events, :through => :events_interests
event.rb => has_many :events_interests
has_many :interests, :through => :events_interests
has_many :users_interests, :through => :interests
has_many :users, :through => :users_interests
interest.rb => has_and_belongs_to_many :users
has_and_belongs_to_many :events
events_interests.rb => belongs_to :interests
belongs_to :events
users_interests.rb => belongs_to :users
belongs_to :interests
Whew..ok So I wanted to created a named_scope of that find all the events that share interest with a particular user. Here is some code someone helped me with.
named_scope :shares_interest_with_users, lambda {|user|
{ :joins => :users_interests,
:conditions => {:users_interests => {:user_id => user}}
}}
When i run from the controller =>
#user = User.find(1)
#events = Event.shares_interest_with_user(#user)
I get the error :
uninitialized constant Event::EventsInterest
Can anyone see what i messed up?
You must have named something wrong along the way. At a glance I'd say you have a file or class named incorrectly. Remember model names MUST always be singular, both in file and class names or else Rails won't make the connection. Another source of your problem is that arguments to belongs_to must also be singular. Even if you had got things right, the HABTM relationship in interests with users would have thrown an error when you ran the named scope.
I was able to solve your error with the following models.
user.rb
class User < ActiveRecord::Base
has_many :users_interests
has_many :interests, :through => :users_interests
has_many :events_interests, :through => :interests
has_many :events, :through => :events_interests
end
users_interest.rb
class UsersInterest < ActiveRecord::Base
belongs_to :user
belongs_to :interest
end
interest.rb
class Interest < ActiveRecord::Base
has_many :users,:through => :users_interests
has_many :users_interests
has_many :events_interests
has_many :events, :through => :events_interests
end
**events_interest.rb
class EventsInterest <ActiveRecord::Base
belongs_to :interest
belongs_to :event
end
event.rb
class Event <ActiveRecord::Base
has_many :events_interests
has_many :interests, :through => :events_interests
has_many :users_interests, :through => :interests
has_many :users, :through => :users_interests
named_scope :shares_interest_with_users, lambda {|user|
{ :joins => :users_interests,
:conditions => {:users_interests => {:user_id => user}}
}
}
end

Resources