Adding A LOT Attributes to Rails Devise - ruby-on-rails

I am implementing a login system, which require to collect a lot of user data, for example:
college, course, graduate year, start year, hobby, .... about 20-30 of them.
Is it wise to put them all into Devise? Or create another Model to handle that?

Its not good idea to put so much of data in devise model. Devise model record is always fetched from database for every request.(You can see it from logs)
You can add it in another model and add association.
e.g. you can add profile model
Assuming you have User model as devise model.
You have to take care of creating profile record after either User creation or User logs in first time or as per your requirement.
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
class Profile < ActiveRecord::Base
belongs_to :user
end

You can create a user_info model with this association, in user.rb
has_one :user_info
On, sign_in it should create an instance of user_info if its not present in the databse
This approach would be better if you want to add 20-30 columns

Related

RoR modelling for different users, Devise, Active Admin

I have a single users table through Devise. Branching off this table are 3 other models (author.rb, seller.rb and buyer.rb) with each having a one to one relationship with the main Users table.
The reason for this is each have some unique attributes and I want to keep the main Users table tidy. I am using active admin and want to avoid redundant fields when registering a new user.
Currently I am using enums to assign user roles:
enum role: [:author, :sellers, :buyers]
The problem is when I set a role it works in the sense that I can restrict what a user sees based on that role however there is a big issue I have below.
The problem:
I want to be able to register an Author. Everything good so far. But I also want to be able to register a Buyer and then associate that buyer with the author as two different users. At the moment a user is becoming both at the same time through nested forms in active admin I used which is not what I want. I want a user to be a buyer and the other user to be an author.
Maybe I don't have my relationships set up correctly for this? Or it could be a problem in active admin?
class Author < ActiveRecord::Base
belongs_to :user
end
class Buyer < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :author
has_one :buyer
end
Basically I want to be able to register two different users and after that associate them and I don't know how to do this. Any advice much appreciated.

Rails_Admin Multiple 'User' Models + Devise

So I have installed Devise and rails_admin in my current setup. I'm kinda trying out rails right now for administration scenarios.
Since I figured many administration required multiple 'user' models, I ran into trouble in figuring out the right way to design and arrange their relationships.
So right now I have a User (devise) model.
For the User Models, I decided to separate the models I need (Admin, Student(example), Professor(example)).
I read around and found out that STI seems to be the solution here, so I set them up to be
class User < ActiveRecord::Base
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
end
class Student < User
end
class Professor < User
end
In rails_admin, User CRUD is basically done, and using this setup I managed to find the configuration I want. Creating a Student, for example, will be recognized as a user. However, what I'm having problems is now on whether I have the correct setup or not since I might actually need a Student to have their own attributes (like student_id or major? just throwing things here). Using the previous setup I mentioned will only enable me to create them using the User model attributes, not the Student itself.
I also read from somewhere that I need to have a column 'type' in User that can be filled with either Student or Professor, but I'm having trouble in combining all of this solutions.
Any pointers/suggestions on how I should proceed now? Much appreciated.
If you decide to use Single Table Inheritance:
the type attribute is used by Rails to reach the appropriate model and its done automatically for you. i.e. when you do a Student.new, the type attribute is set to "Student"
the attributes of all the inherited classes ( Student, Professor, etc) are all stored in the users table. This means that both Student and Professor will have major, fees_schedule, etc (which are not normally applicable to professors).
Here's the documentation about Single Table Inheritance
On the other hand, you might want to consider Polymorphic Associations where each table is separate and associated along the lines of:
class User < ActiveRecord::Base
belongs_to :member, polymorphic: true
...
end
class StudentMember < ActiveRecord::Base
has_one :user, as: :member
...
end
class ProfessorMember < ActiveRecord::Base
has_one :user, as: :member
...
end
Read more about Polymorphic Associations here
Polymorphic Associations seems more appropriate in your case as there are probably many different attributes for students, professors, admin staff, etc, and it will look pretty messy if you dump all of them into the users table.

Creating a profile for users model in rails

I have a users model in my rails application. It has a name attribute only along with email & password added to it for login via Devise. I want to create a model Profile for users. How shall I create it. Either by adding profile attributes to existing User model or by creating a model Profile and adding a belongs_to association to it.
Adding more attributes to your user model will make your user object a bit heavy and is not the best idea given that you'll be calling that object quite often. For instance, to verify a user, you don't need to load the profile attributes like location or date of birth, which the current_user helper would. So, its better to extract profile attributes in a separate model and adopt either of gabreilhilal's approaches.
Well, it depends on the requirements you have.
If a user can have only one profile and you are just going to add some attributes related to the user, there is no reason to create a new class to it.
However, even if a user can have only one profile, you might want to do some normalisations. If so, you might remove some attributes from the users table to create a table profiles, and you will have a one-to-one relationship.
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
Well... depending on your requirements, you might have a situation where a user might have more than one profile. If so:
class User < ActiveRecord::Base
has_many :profiles
end
class Profile < ActiveRecord::Base
belongs_to :user
end
To summarise, there is no right or wrong... it will depend on the requirements you have, as well as you design decision.

Automatically insert new record into association when using has_one or has_many

Right now I have two tables, users and roles, of course roles has a user_id and the roles model has belongs_to :user and the user model has has_one :role. The question I'm wondering is, how do I have the User model create the new record in the Role model. I understand I can do this outside of the model just as easily as I create the user, but I figure it might be more streamlined and keep everything in one spot and simplify it if I do it in the User model. Are there any suggestions on how I could easily do this without knowing the id of the user before it's saved?
Note: (I would only allow this when new_record? is true, otherwise it will be forbidden.)
I'm doing something similar with user & their settings, probably this could work for you:
class User < ActiveRecord::Base
#...
has_one :role
before_create :build_a_role
private
def build_a_role
self.build_role(role_att: value)
end
end
Then, when the user is saved, the role is saved too.

rails attaching database entry to logged in user

I'm new to rails and am done setting up my login system. However, I want someone to be able to make a new blog post and attach it to their account when logged in. How can I attach a post to their user_id as well as list all their previous posts?
Define a model posts ( should have column name user_id )
model Post < ActiveRecord::Base
belongs_to :user
end
In user Model
model User < ActiveRecord::Base
has_many :posts
end
With the above defined associations user_id will be a foriegn key to User model so you can
get all posts by user something like below
User.find(id).posts
There are quite a few different approaches, but John Nunemaker's user_stamp gem is pretty straightforward and simple to get running.
https://github.com/jnunemaker/user_stamp
Just add a creator_id and updater_id to your table, a single line in your ApplicationController, and it'll do the rest!
You can associate models with each other by following this guide on rails associations. One solution for you might be:
class Post < ActiveRecord::Base
end
class User < ActiveRecord::Base
has_many :posts
end
You just have to make sure that your posts table has a column called user_id. Assuming your user table is called users. this will set up a one to many association between users and posts. From a User instance you will be able to do user.posts and get a list of the associated posts for that user.
The guide is much better at explaining this stuff and it's worth your while to read the whole thing--even the parts you don't need right now.

Resources