Devise with multiple models - ruby-on-rails

How do I setup devise with more than one model?
I've already tried using rolify and cancan to setup separate roles in my database, but each role has a different way to authenticate themselves to login. For example, a student will have a student_number, and a lecturer will have a username but no student_number.
Also there is a bunch of other attributes a lecturer won't have that a student will and vice versa.
I'm new to rails 4.

It looks like classes and inheritance can come handy in this case.
What about defining a User mode and the let Student and Lecturer inherit from that class?
class Student < User
# student's peculiar attributes
end
class Lecturer < User
# lecturer's peculiar attributes
end
Then you can have two separate controllers and corresponding views. The the login page might have two links to the proper login pages.

I resolved this issue using a User model and a "has_one" Profile model attached to User, all users log in using the same table but devise load another data saved in Profile.
Other option is use just User model and left student_number empty when the user is not an student.

Related

How to split Devise user into different types?

I want to split Devise user into different types? Like, for example: user go to the registration page and sign up, but based on whether they're a teacher or a student they will registered and login to see different navbar? How would I do that using a checkbox?
It is excellently explained in their Wiki.
In my opinion you should consider option number 1. and 3:
Separate model for student and teacher, if they have different attributes
One model for both with additional column role. It will be appropriate if models have the same attributes.
Then on your views just check what is the role / type of user and present proper content.

How do I set up my model associations for an conference registration app?

I've been playing around with writing a RoR 4.2 app that will allow the following behaviors:
Admin users to create a list of conference courses that will include topic, description, etc
Conference attendees can register with the website and then select the conference courses they'd like to attend.
Conference attendees should not be able to create conference courses, only to select from a list of courses listed in the database and to select them to attend. The must be a way to associate many users with the same course.
When a user selects a course, the seating capacity for that course should be decremented (the details of this aspect of the solution are a secondary requirement at the time)
For the sake of discussion, let's say I am using Devise with user roles all figured out and configured. So I have one user.rb model/table.
I also created a model/table called course.rb.
I created a join model/table called course_selection.rb.
I configured these tables using the has_many through associations with the join table belonging to each like so:
class User < ActiveRecord::Base
has_many :course_selections
has_many :courses, :through => :course_selections
end
class Course < ActiveRecord::Base
has_many :course_selections
has_many :users, :through => :course_selections
end
class CourseSelection < ActiveRecord::Base
belongs_to :user
belongs_to :course
end
I have this set up and am able to create new users, but the users with non-admin roles are able to create courses (but I haven't set up any kind of role based exclusions for these users to prevent them from creating courses). When I call a RESTful route such as
http://localhost:3000/users/3/courses
I am expecting to see only a list of courses associated with this particular user. Instead I am seeing ALL the courses listed in the database.
My questions are:
Can the model associations strategy I've selected be used to accomplish the behavioral goals I've specified?
How would the controllers be set up so that a user's course selection is established, but that they are not using the new/create methods to actually create the course?
How would the forms be set up (I'm using simple_form) to allow the user to select from the list of existing courses?
Thanks for your help. I haven't found any tutorials that seem to address this challenge.
Can the model associations strategy I've selected be used to accomplish the behavioral goals I've specified?
Yes, those models are a fine start.
How would the controllers be set up so that a user's course selection is established, but that they are not using the new/create methods to actually create the course?
The typical Rails REST-like way is to have a controller CourseSelectionsController that manages the association.
Suppose you have a view page where a user can select a course. The view would submit the data to the CourseSelectionsController, with params user_id and course_id. The controller then creates the CourseSelection model, which associates the user and course.
The CourseSelectionsController would have typical actions for "create", "read", "delete". If the course selection also has other data, such as a price, or time slot, etc. then there can be an action for "update".
By the way, in your kind of application, the middle model is often called Enrollment instead of CourseSelection, and the REST controller is called EnrollmentsController.
How would the forms be set up (I'm using simple_form) to allow the user to select from the list of existing courses?
Typically in app/views/course_selections. The form is based on CourseSelections (not Users, and not Courses). The form shows a list of courses. When the user submits the form, it does a PUT (or POST) to CourseSelectionsController.
If you want the form to be able to handle multiple courses, one way is to use AJAX as each course is selected or unselected. Another way is to use multiple select fields, and make a controller method that can iterate on all the selected/unselected courses.

Rails 4 Devise and STI

I read the two posts here and here, but still have trouble figuring out how everything is tied together. Basically I have 2 types of users, Trainers and Clients. They share some common attributes (email, phone, first name, last name, etc), but they will also have some custom attributes.
Assuming STI is the way to go, I would have 3 models:
User (devise)
Trainer (inherits from User)
Client (inherits from User)
When the user signs up, they should be able to use the same form and just select from a drop down if they're a trainer or client. Once the form is submitted how do I go about specifying the type of user that has just been created? Do I need logic in the controller to check the user type, and then run Trainer.create() or Client.create()?

View association object

Hi i have a table that is called contractors this is acting as the users model for logging into the system. I have a second table called employees. I have created the relationship between the two tables. contractors has_many employees and employees belong_to contractor.
The employee table has a field for contractor id as a foreign key.
When the contractor logs into how can i set the view to only show him the employees that belong to him
Thanks in advance!
I don't know how your authentication works, but sou should have something like current_user helper which retrieves the currently logged in user from session. Devise gem, for example, creates it automatically.
#employees = current_user.employees

How to allow user to set a profile attribute when signing up?

My Profile model has a full_name attribute, but I want it to be set when the user signs up by the User create method. The profile and user are two separate models with two separate controllers. Can I do this? If so, how?
Wouldn't it make more sense to have full_name on User? Then each Profile will have a User and the Profile can just delegate the full_name accessor to its User; or the view could just use profile.user.full_name instead of profile.full_name.

Resources