I have a container class I need to name, today it is called "EnrollmentApplication". It is a container of one type of application.
I've decided to push some of the business logic specific to different types of applications into a delegate associated with the application via a polymorphic relationship, to allow support for different types of applications. I'm struggling with a good name for the class and the relationship:
today:
EnrollmentApplication and applicationable
It's no longer just an application, but a collection of tasks and steps , kind of a workflow.
Portfolio and portfoliable....
ApplicationContainer and containable....
thanks
Joel
If the name of your class is called Enrollment then the following could work:
class Enrollment < ActiveRecord::Base
has_many :enrollment_applications
has_many :enrollments, :through => :enrollment_applications
end
Then you need your join table:
class EnrollmentApplication < Active Record::Base
belongs_to :enrollment
end
I really don't know if this will work because rails might complain about only having one id. I'm gonna try this when I get home to see if you can do this because I am actually setting up and app where user has many users. Anyway, keep us posted on your progress.
Related
I'm building a rails application that allows users to call one of many web services with user-defined credentials that are saved in an instance of the service type. The user will create an instance of the Service model, that has_one instance of another model (that defines the service type). Where it gets tricky is that there are different service types. So the Service instance needs to link to one of many different possible models, but I'm not sure how to do this.
For example the Service model, which belongs to a user, will have a has_one reference to only one of the following classes:
ServiceType1
ServiceType2
ServiceType3
I want to know how I could have a reference field with model as an optional field.
Would the following work?:
Service.reference - has an ID of the ServiceTypeX instance
Service.serviceType - selects the correct ServiceTypeX model
Or could it be managed somehow with a has_one through relation?
I want to allow many different service types in the future, so having a reference field for each would not be the best approach.
Apologies in advance for unclear explanation... it's very hard to clearly explain.
Thanks to spickermann for the comment. Polymorphic Association did the trick!
This is what I did:
class Service < ApplicationRecord
belongs_to :serviceable, polymorphic: true
...
end
module ServiceTypes
class ServiceType1 < ApplicationRecord
has_one :service, as: :serviceable
end
end
I'm seeking brainstorming input for a Rails design issue I've run across.
I have simple Book reviews feature. There's a Book class, a User class, and a UserBook class (a.k.a., reviews and ratings).
class User < ActiveRecord::Base
has_many :user_books
end
# (book_id, user_id, review data...)
class UserBook < ActiveRecord::Base
belongs_to :user
belongs_to :book
end
In the corresponding book controller for the "show" book action, I need to load the book data along with the set of book reviews. I also need to find out whether the current user (if there is one) has contributed to those reviews.
I'm currently running two queries, Book.where(...) and UserBook.where(...), and placing the results into two separate objects passed on to the view. Now, while I could run a third query to find whether the user is among those reviews (on UserBook), I'd prefer to pull that from the #reviews result set. But do I do that in the controller, or in the view?
Also worth noting is that in the view I have to draw Add vs Update review buttons accordingly, with their corresponding ajax URLs. So I'd prefer to know it before I start looping through a result set.
If I detect this in the controller though, I'll need three instance variables passed in, which I understand is considered distasteful in Rails land. Not sure how to avoid this.
Suggestions appreciated.
This smells like a case for has_many through, which is designed for cases where you want to access the data of a third table through an intermediate table (in this case, UserBook)
Great explanation of has_many :through here
Might look something like this:
class User < ActiveRecord::Base
has_many :user_books
has_many :users, through: :books
end
Then you can simply call
#user = User.find(x)
#user.user_books` # (perhaps aliased as `User.find(x).reviews`)
and
#user.books
to get a list of all books associated with the User.
This way, you can gain access to all of the information you need for a particular user with a single #user instance variable.
PS - You'll want to take a look at the concept of Eager loading, which will prevent you from making extraneous database calls while fetching all of this information.
I have some problems understanding the has_one relation.
I have two models Planning and Sport. A Planning is concerned by one Sport and a Sport can be found in many Plannings. So I defined my Planning this way:
class Planning
...
has_one :sport
...
end
And I didn't add anything in Sport regarding the Planning.
In my mind, this would allow me to access planning.sport but I don't mind if I can't find sport.plannings (which makes no sense).
The problem is that when I try to create a new Planning using my ActiveAdmin interface, I have the following error as soon as I try to access the plannings/new page:
undefined method `planning_id' for #<Planning:0x30d8570>
What I understand is that it checks in Sport that a planning_id exists, but my understanding was that there was just a sport_id in the Planning, not the opposite...
What did I do wrong? Do I need to use an intermediary model? Is this jsut linked to ActiveAdmin?
Thanks!
What you need is
class Planning
...
belongs_to :sport
...
end
class Sport
has_many: plannings
end
You can think of it like, whoever has the foreign key is like the child. So here planning has the foreign key of sport. So it is a child of Sport and it belongs to sport.
I am implementing a job search application in rails where A user can signup for three different profiles/roles.
Employer
Worker
Enterpreneur(has his own company)
User can choose more than one profile/role.
(I am using the Devise)
My query is that Is it possible to implement the Single Table Inheritance in the above case.?like
CLass Employer < user
CLass worker < user
or what should be the best solutions for database structure to implement the above feature?
Yes it is certainly possible, STI is widely used when models share the same attributes and if you want to be able to query them all together (will help with speed and simplicity since you are loading one db table). You may also share code between the Classes, you only need to put a method once in the parent class and have all the children inherit.
Side note, make sure you are following ruby naming practices, capitalize the classes
Class Worker < User
EDIT (suggested approach)
I would not have these roles inherit from the User, you can still use STI but create another model
Class User < ActiveRecord::Base
has_many :profiles
Class Profile < ActiveRecord::Base
belongs_to :user
Class Employer < Profile
Class Worker < Profile
Class Entrepreneur < Profile
You might want to watch this railscast -- this is what I just recently implemented. It uses a bitmask column in the database. I also paired it with cancan to handle my permissions.
I'm trying to build a student portal in Rails 3, but I'm having some problem.
The idea is to have a users table that contains all basic data for a given person. See the UML/E-R below for example attributes.
A user can be both an Assistant and a Student at the same time.
Assistant and Student should inherit from User.
The idea was to inherit directly from the User, like this.
class User < ActiveRecord::Base
# ...
def awesome?
[true, false].sample
end
# ...
end
class Student < User
has_one :student
has_many :registered_courses, through: :students
end
Student.new.awesome?
This makes the relations in the student model very strange.
has_many :registered_courses, through: :students
I want to be able to do something like this in the end.
student.full_name
student.pin_code
student.registered_courses
One solution would be to implementing the method by hand, like this
class Student < User
has_one :student
def pin_number
student.pin_number
end
end
But it looks really strange to refer to a student object inside the student model.
Is there a clearer, better way of doing this?
Here is an example UML/E-R. I've tried to keep this example clean by removing non relevant attributes. That is why there are so few attributes in the registered course entity.
STI is not a good choice for this the way that you have articulated it here, since users can be both students and assistants. When you are using STI, you generally add a type column to specify which subclass the record really belongs to. If both Student and Assistant inherit from User, then that really isn't an option, since you'd be forced to create duplicate User records for someone who is both an Assistant and a Student.
I think you'd be better off simply having Student and Assistant rows that belong_to a Student, and then delegating the elements that are contained in User back to the User object.
I feel like Inheritance is a bad move here. If you're going to have STI like this it HAS to be one or the other.
Instead throw all your logic into the User model, all your data is there anyway. Plus since Student & Assistant aren't mutually exclusive there shouldn't be any methods that will override each other.
Why not STI?
STI is mainly meant for objects that contain the same data, but does different things with them.
For example, I have a specification that contains multiple processes(ex. build and test). So I have a order that contains processes.
process_1:
order_id: 1
specification: foo
type: build
process_2:
order_id: 1
specification: foo
type: test
In this example the only thing that changes in the data is the type, but because the type changes I know what process to perform from the specification.