Ruby on Rails - relation one to four - ruby-on-rails-3

In rails i have two models, Groups and Users. How can i do that the user have only one group and a goupr have max 4 users?
I have tried this in users.rb belongs_to :group and this in groups.rb has_many :users
Thanks

Use a custom validation for example:
class Group
has_many :users
validate :limit_users
private
def limit_users
errors.add('Only 4 users allowed') if users.size > 4
end
end
class User
belongs_to :group
end

Related

Rails how to find records where the has_many relation exists?

In the below association, I want to collect all Users who don't have any projects->
class User < ActiveRecord::Base
has_many :projects, :foreign_key => :user_id
end
class Projects < ActiveRecord::Base
belongs_to :user, :foreign_key => "user_id"
end
From User model, how can I get all the users that do not have any projects? I tried using includes and join but didn't get the expected result
You could try:
User.where.not(id: Project.pluck(:user_id).uniq)
Breaking it down:
Project.pluck(:user_id).uniq
will give you an array of user_ids from your projects. Essentially, users with projects.
Then:
User.where.not(id: Project.pluck(:user_id).uniq)
returns users who have an id that is not in the array of users with projects.

rails has_many at least one children has the value

Let say I have a Group of Users and User has a enum, which described it's mood.
class Group < AR::Base
has_many :users
class User < AR::Base
belongs_to :group
enum mood: %i(good bad ugly)
How can I find all groups, where at least one User has the good mood?
Which index should I add for optimizing this query?
You can use joins method.
Group.joins(:users).where("users.mood = ?", User.moods[:good])
You can add this into your migration
add_index :users, :group_id

Rails 3 - associations "through" - how to get the data from DB?

I have a problem with fetching data from DB, where is between models association kind through.
On my site, I have a categories, like a sports, news, weather etc. When an user is logged in and has a selected the categories, from which want to see the articles, then I would like to display only these articles.
Here's how looks like my models:
class User < ActiveRecord::Base
has_many :user_categories
has_many :categories, :through => :user_categories
end
class Category < ActiveRecord::Base
has_many :articles
has_many :user_categories
has_many :users, :through => :user_categories
end
class UserCategory < ActiveRecord::Base
belongs_to :user
belongs_to :category
end
class Article < ActiveRecord::Base
belongs_to :category
end
But I still can't find the way, how to get all articles from user's selected categories... I tried something like
Article.joins("LEFT JOIN categories ON category.id = user_categories.category_id").where('user_categories.user_id = ?', current_user.id)
I would grateful for every advice!
Thank you
Here's one way to do it:
Article.where(:category_id => current_user.categories.map {|c| c.id})
That will create 2 queries. First one will return a list of the current user's categories. Then the ruby map function will create an array containing the ids of those categories. The second query will then return a list of articles whose category_id is in the array of ids. The second query will look something like:
select articles.* from articles where articles.category_id in(1,2,3);

rails - what is the best/most efficient way to associate these models

In my application I have the following situation:
User belongs_to Group
Group has_many Users
Project belongs_to User
User has_many projects
The following is also true:
- Each Group will have one BaseCase
- Each Project will have multiple Scenarios and one BaseCase(depending on the Group the Project User belongs to)
- Scenario and BaseCase is the same type of object (let's call this Data)
- The default values for each Scenario are the BaseCase values for the Group, but the User can change these default values to create the specific Scenario
I am not sure how to capture all these relationships through associations efficiently, does anyone have any ideas? thanks
If I understand correctly, then something like that
class User
belongs_to :group
has_many :projects
end
class Group
has_many :users
has_many :projects, :through => :users
has_one :base_case
end
class Project
has_many :scenarios
has_one :base_case
belongs_to :user
has_one :group, :through => user
has_one :base_case, :through => :group
end
class Scenario
belongs_to :project
has_one :base_case, :through => :project
before_create do
self.attributes = self.base_case.attributes.except(:group_id, ...)
end
end
class BaseCase
belongs_to :group
end

Find all records NOT in a many-to-many association

In Rails 3 with ActiveRecord, I have 2 models (Users and Tasks). These models are linked together with a has_many :through association on another model, Assignments. How can I find all Tasks that are NOT associated to a particular user?
class User < ActiveRecord::Base
has_many :assignments
has_many :tasks, :through => :assignments
end
class Tasks < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments
end
class Assignments < ActiveRecord::Base
belongs_to :users
belongs_to :tasks
end
Short 'n sweet:
Task.all - user.tasks
Avoid loading user tasks:
Task.where('id not in (?)', user.task_ids)
I couldn't figure out how to do it with an outer join in AR.
I'm going to assume you want those tasks without any associated user, rather than not associated to a user in particular.
Tasks.joins('left outer join assignments on assignments.task_id = tasks.id').where('assignments.* is null')