Rails how to access users status on project level - ruby-on-rails

I have two models User and Project which are in has_and_belongs_to_many association
The user model has a column status
i can access the status of a user who is in project like
project.user.status
but a user can be in different projects i want his status to be on project level instead of on his id

If I understand your question correctly, the problem is that you need to associate the status of the user to one of potentially many projects that the user is associated with, but you are associating a single status to a single user instead of the project.
In that event, you need to abstract this association to an additional model, for instance "UserProjectStatus" which would be associated with both the User and the Project. You can do this using the has_many, through association. This would end up with something along the lines of:
class Project < ApplicationRecord
has_many :user_project_statuses
has_many :users, through :user_project_statuses
end
class UserProjectStatus < ApplicationRecord
belongs_to :user
belongs_to :project
end
class User < ApplicationRecord
has_many :user_project_statuses
has_many :projects, through :user_project_statuses
end
There is a good overview of this any many other Rails ActiveModel associations at https://guides.rubyonrails.org/association_basics.html#the-has-one-through-association.
Hope this helps!

Related

Using a junction table with its own relationship

I'm creating an app that has a User and a Plugin model. A user can have multiple plugins and a plugin can belong to multiple users, which I've implemented using a junction table.
class Plugin < ActiveRecord::Base
has_many :user_plugins
has_many :users, through: :user_plugins
end
class User < ActiveRecord::Base
has_many :user_plugins
has_many :plugins, through: :user_plugins
end
class UserPlugins < ActiveRecord::Base
belongs_to :user
belongs_to :plugin
end
However, I then want to store arbitrary data for each user plugin (for example, things like api keys, options etc that can differ for each plugin.).
My initial approach was to have a user_plugins_options that joined on user_plugins, but I can't seem to get this to work correctly.
class UserPluginOptions < ActiveRecord::Base
belongs_to :user_plugins
end
My question, how should I go about approaching this to best work with ActiveRecord?
I think you misnamed your class, as the table is user_plugins but the model is UserPlugin. It’s plausible you are running into issues because of this.
Agree with Alex. Why don’t you create a json field on UserPlugin called options and keep a hash of plugin specific values here.
If you must have another table, you should add a has_one :user_plugin_option to your UserPlugin

has_many through relation in active model serializers Rails API

I have many to many relation between users and projects through user_project. I know I could simply add has_many :projects in User Serializer (and vice versa in project serializer) to nest projects inside users.
But I also have a few additional fields in user_projects table (eg. start and end dates for user's participation in a corresponding project) and I have no idea what is the correct way to include them in the returned json. Should I create a special serializer for projects that are returned inside user with start_date included as a project's attribute or there's another way to do that?
The best way to do this would be to establish a 'has-many-through' (HMT) relationship between the user and project models and create a serializer for relationship's model.
class UserProjectSerializer < ActiveModel::Serializer
...
end
This will then be used in the UserSerializer via:
has_many :users_projects
The reason is that the relationship between the models contains additional data.
To implement the HMT, you'll need to create the user_projects model and define the HMT relationship in the related models:
users_project.rb
class UserProjects < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
user.rb
class User < ActiveRecord::Base
has_many: users_projects
has_many: projects, through: :user_projects
end
project.rb
class Project < ActiveRecord::Base
has_many: users_projects
has_many: users, through: :user_projects
end
I have had a similar problem before and I made use of rabl. There is a good tutorial on railscasts to help you get started.

ruby on rails -- can two Models belong to each other?

My group is making a Project Management System for our course, and it's my job that when a user is logged in, that they see the projects they are part of, and also that the projects listed have a members list of current members of that project.
(Also will need an add/delete member function later)
My question is, since the rest of the group have already set it up so that Projects belong to Users, is it possible to have Users belong to Projects in order to set up this member list and do what I'm talking about?
The relation you are describing is not one-to-one:
when a user is logged in, that they see the projects they are part of
This implies that a user can have several projects. You also specified:
[project has a] list of current members of that project
This implies that a projet can have several users.
In conclusion, you need a many-to-many relation between your User and Project models.
This is a basic many-to-many relationship in Rails:
class User < ActiveRecord::Base
has_many :user_projects
has_many :projects, through: :user_projects
class Project < ActiveRecord::Base
has_many :user_projects
has_many :users, through: :user_projects
class UserProject < ActiveRecord::Base
belongs_to :user
belongs_to :project
validates :user_id, :project_id, presence: true
The UserProject model is a join table. What I have done in my code is an explicit has_and_belongs_to_many, which let you have more control over the join table. (example: add a role column in the UserProject table, containing data like project_creator or simple_member)
The UserProject model could be named Membership to be more explicit. I used both models' name to make UserProject, as we usually do in Rails' naming convention.

How to implement projects with project admins in Rails

What I'm looking for is an appropriate way to set up a system where users can create projects and therefor become the admin of that project. The user can then add other admins to the project. Finally, other non-admin users can join the project.
I want to be able to verify whether a user is an admin of a project to check whether he has edit/update privileges. Any thoughts?
I figure I'll probably have a users_projects table and a projects_admins table, but I can't figure out how that translates to Rails relationships....
Thanks!
Ok, I will give it a try, but without too much code here in.
I see here 3 models:
User
Project
ProjectAdmin
The first 2 are simple models, with some attributes. The third one is the relation between the two and will be a n:m relation. So it is best to use the has-many-through relation here.
class ProjectAdmin < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
class User < ActiveRecord::Base
has_many :project_admins
has_many :projects, :through => :project_admins
end
class Project < ActiveRecord::Base
has_many :project_admins
has_many :admins, :through => :project_admins
end
Of course you have to create additionally the 3 tables by migrations, and add later a similar relation for project users, named then ProjectUser as model. Have at least a look at the rails guide about relations, section "has-many :through".
To add the creator to a project, this should be a one-one relation between the two, so it should be sufficient to have:
class Project
has_one :creator, :class_name => "User"
end
(and of course the creator_id in the migration)

.build method not creating association in the join table

I have three Models setup with the following associations
class User < ActiveRecord::Base
has_many :faculties
has_many :schools, :through => :faculties
end
class School < ActiveRecord::Base
has_many :faculties
has_many :users, :through => :faculties
end
class Faculty < ActiveRecord::Base
belongs_to :user
belongs_to :school
end
and in my controller i go to create a school and assign the user
class SchoolsController < ApplicationController
def create
#school = current_user.schools.build(params[:school])
...
end
end
When I login and submit the form the flash displays success, but the association doesn't build on the join table.
I tried it inside the apps console and it builds the association just fine.
I've been stuck on this for a couple days now and I just cannot figure out what I am missing. Thank in advance for any and all advice
The build method does not save the object. You need to explicitly call #school.save.
Two things: If the schools association is :through a has_many association, you will have to select which parent the School exists through.
So, for instance, if you were to nest School resources under users as in /users/:id/faculties/:id you could create a school via current_user.faculties.find(params[:faculty_id]).schools.build(params[:school]).save
Based on the example code, it looks like the fundamental problem is that the has_many xxx, :through syntax is being used without specifying the id of the faculties record. Remember two things: 1) ActiveRecord doesn't natively support composite primary keys, and 2) you must call #save on associated records created using #build. If you remember these, you should be fine.

Resources