Can someone help me to correct my associations ?
I have the following models:
User, Developer, Application, Comments, Rating, Permission
Requirements:
A user can be a Developer or not.
A user can have Default Permissions and Permissions for each application
A user can install multiple Applications
A user can comment and rate multiple Applications
A developer can develop multiple applications
An application can request a list of permissions.
I already created some associations but I believe its not 100% correct or an easier way to do it exist.
Can someone suggest me a correct way to do it?
You are confusing models with authorization.
You should check out CanCan for role based authorization. For example you don't need your developer model since its just a user with a different role/permissions.
Edit: Changed 'role based authentication' to 'role based authorization'. As the comment below points out the difference between authentication and authorization.
I think this is what you want as far as your model work. You can use a join model to manage your application permissions, and use Rails STI to manage what each type of user can do, whether it's developing or not.
user.rb
class User < ActiveRecord::Base
has_many :apps
has_many :comments, :through => :user_comments
has_many :ratings, :through => :user_ratings
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
end
rating.rb
class Rating < ActiveRecord::Base
belongs_to :user
end
user_comment.rb
class UserComment < ActiveRecord::Base
belongs_to :app
end
user_rating.rb
class UserRating < ActiveRecord::Base
belongs_to :app
end
normal_user.rb (STI)
class NormalUser < User
end
developer.rb (STI)
class Developer < User
end
app.rb
class App < ActiveRecord::Base
has_many :permissions, :through => :app_permissions
has_many :user_comments
has_many :user_ratings
end
permission.rb
class Permission < ActiveRecord::Base
belongs_to :app
end
app_permission.rb
class AppPermission < ActiveRecord::Base
end
I agree with #Mark, don't use STI. The better way will be implement as suggested by #Chris Barretto except for STI and use CanCan for role based authentication. The change for User model will be:
class User < ActiveRecord::Base
has_many :apps
has_many :comments, :through => :user_comments
has_many :ratings, :through => :user_ratings
has_many :roles
end
And there will be another model for Role:
class Role < ActiveRecord::Base
has_many :users
end
If you are using gems like Devise for authentication, it will be much easy.
Related
I have a memberships resource and it belongs to user and club. I want to access the parent attributes i.e for club and user and I read that accepts_nested_attributes_for is used for parent side of a relationship. What should I write in my membership model?
I have searched about it both in stackoverflow and activeadmin docs but I did not get a thorough explanation about solving my problem...
My membership model is:
membership.rb
class Membership < ApplicationRecord
require 'csv'
belongs_to :club
belongs_to :user
end
Also what should i write in my membership resource which I have already registered with AA...
You can mention the following :-
1) has_many: memberships #in user model
2) has_many: memberships #in club model
This will help you access parent attributes from child model :-
membership.user, membership.club
Also, you can mention accepts_nested_attributes_for: memberships in user model.
When you write this, you can then build a common form for user and membership and modify both of them simultaneously. To achieve this, you will have to allow membership attributes in users_controller.rb.
The following should work(Similar question):
class Club < ApplicationRecord
has_many :memberships, :dependent => :destroy
has_many :users, :through => :memberships
accepts_nested_attributes_for :membership
end
class User < ApplicationRecord
has_many :memberships, :dependent => :destroy
has_many :clubs, :through => :memberships
accepts_nested_attributes_for :membership
end
class Membership < ApplicationRecord
require 'csv'
belongs_to :club
belongs_to :user
accepts_nested_attributes_for :club
end
I have the following models:
class User < ActiveRecord::Base
has_many :forum_users
has_many :forums through: :forum_users
end
class Forum < ActiveRecord::Base
has_many :forum_users
has_many :users through: :forum_users
end
class ForumUser < ActiveRecord::Base
belongs_to :forums
belongs_to :users
end
ForumUser has an additional "permissions" field to designate what the user can and cannot do within a particular forum.
The problem is that the "permissions" field on ForumUser is much more difficult to access than fields on Rails models normally are. In an ideal world, I would be able to make requests like:
user = forum.users.first
user.permissions
But once it's assigned, the User doesn't even remember the Forum it was attained through in the first place. It seems like there has to be a simple and straightforward Rails way of doing this. If so, what is it?
Right now I'm trying to create a one-sided follow/unfollow relationship where a user can follow/unfollow a celebrity. Despite the gems available I'd like to learn how to create this from scratch.
The posts I've found online seem to only incorporate a self-referential style where a model instance can only follow one of its kind (a user can only follow other users). As a starting point point I've used this post for the initial setup. I'm just not sure how to re-configure the associations for models:
class User < ActiveRecord::Base
end
class Following < ActiveRecord::Base
end
class Celebrity < ActiveRecord::Base
end
You are looking for a "many to many" relationship. You can find more detailed information about this relation here. With your models as examples it would look like this:
class User < ActiveRecord::Base
has_many :followings, :dependent => :destroy
has_many :celebrities, :through => :following
end
class Following < ActiveRecord::Base
belongs_to :user
belongs_to :celebrity
end
class Celebrity < ActiveRecord::Base
has_many :followings, :dependent => :destroy
has_many :users, :through => :following
end
I am making a job application where the user registers and has a profile, can create companies and withing the companies jobs. To explain a bit easier, a simple LinkedIn.
User has_one Profile (thinking of using the gem Virtus or Cocoon so user can access attribute from Profile and not using accepts_nested_attributes_for)
User has_many Companies
User has_many Applications to many jobs
I somewhat know how the application should be modeled but not completely sure and would appreciate some feedback and help. I will post what I think it should be and hope to get some suggestions. Thanks in advance!
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
has_many :applications
has_many :jobs, through: :applications
has_many :companies
end
class Profile < ActiveRecord::Base
belongs_to :user
end
class Company < ActiveRecord::Base
has_many :jobs
end
class Job < ActiveRecord::Base
belongs_to :company
end
class Application < ActiveRecord::Base
belongs_to :user
belongs_to :job
end
I've been reading up on a bit of STI Inheritence examples for Rails,
While it looks like it would suit my needs (User role/types inheriting from a base class of user). It seems like it doesn't handle a user having multiple roles too well. Particularly because it relies on a type field in the database.
Is there a quick and easy work around to this?
I'm not sure if STI is the right solution in a user role/user scenario - I don't think of User roles/types as a specific form of user. I would have the following schema:
class Membership < ActiveRecord::Base
belongs_to :user # foreign key - user_id
belongs_to :role # foreign key - role_id
end
class User < ActiveRecord::Base
has_many :memberships
has_many :roles, :through => :membership
end
class Role < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :membership
end
Another way of doing this would be to use has_and_belongs_to_many. You might also want to check out the restful_authentication plugin.
A good workaround for your problem could be the easy_roles gem. You can find it on github.
As the others already said STI is not the way you can implement your stuff.
Just like Andy said, has_and_belongs_to_many is another way to do this.
# user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
# role.rb
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
Note: You still need the association table in your database but it's just hidden from your models.