Given association in User class:
has_many :followers, through: :follows_as_fallowable,
source: :user
It returns user instances that follow a given user. But when i started to dig deeper i realized that i don't completely understand why does this association(user.followers) returns User objects.
Based on what? I know that it can deduce by name of the association or class_name hash argument, but neither of these actually matters in this case.
I don't have Follower model and i have not provided class_name attribute.
Source parameter just say that it should search by user column in join table.
So how does Rails know that it should select from Users table?
EDIT:
follow_as_followable is another association in User model:
has_many :follows_as_fallowable, class_name: 'Follow', as: :followable
Rails would be picking up knowledge of the User through the follows_as_fallowable relationship, using the association name specified by :source, which is :user (e.g. the User model).
While it's not show in the question, it's likely that the model containing follows_as_fallowable has a belongs_to :user relationship defined, hence the use of source: :user to specify which relationship through which to navigate.
You can see more information in The has_many :through Association section of the Active Record Associations guide.
Related
I'm trying to set up models in such a way that Users can create Lessons and then other users can sign up for them.
Right now my models are set up like this:
class Lesson < ApplicationRecord
belongs_to :teacher, class_name: 'User'
has_many :students, class_name: 'User'
end
class User < ApplicationRecord
has_many :lessons
has_many :students, :through => :lessons
end
I want to be able to access the users signed up for a lesson by #lesson.students for example. I'd also like to be able to get all the lessons that a student is participating in (can't really see how I'd do this with my current set up).
Are my model associations right for how I'd like to use them? If so, how can I create the migrations to add the necessary references to my database models?
If you want the ability to create nested resources from it's parents then you have to add:
accepts_nested_attributes_for
to the parent model.
Also, I recommend you to read how to set up has_many through relationships, you need a join model for rails to do its magic and link the 2 models
Once you set everything up, create the join model (with it's respective foreign keys, one for lesson and the other for user) rails will take care of the associations between the models, allowing you to do things like:
User.last.lessons #lessons created by the last user
and
Lesson.first.users #users subscribed to a lesson, in this case the first one
I have two models, a User model and a Task model. Prior to setting up the new relationship, there was a simple has_many and belongs_to relationship, ex:
class User < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to :user
end
This relationship in my application really represents the user that created the task record, for example when a user creates one it sets the current user's id equal to the tasks.user_id.
I also want another relationship (the same exact type) for an "assigned" feature. What this means is that the relationship above represents the creator of the task, while the assigned_id represents who it is assigned to.
However, the assigned_id can be a User, Vendor, or Carrier. Hence the polymorphic relationship. I've set this up on my Task model and it now has an assignable_id and an assignable_type column on it in the database.
I added this to my Task model: belongs_to :assignable, :polymorphic => true.
What line can I add to make this association work in the User model. There already is the has_many :tasks but this is for a different purpose. How can this be done?
Try the below:
has_many :assigned_tasks, class_name: 'Task', as: :assignable
What inverse_of does mean in mongoid associations? What I can get by using it instead of just association without it?
In a simple relation, two models can only be related in a single way, and the name of the relation is automatically the name of the model it is related to. This is fine in most cases, but isn't always enough.
inverse_of allows you to specify the relation you are referring to. This is helpful in cases where you want to use custom names for your relations. For example:
class User
include Mongoid::Document
has_many :requests, class_name: "Request", inverse_of: :requester
has_many :assignments, class_name: "Request", inverse_of: :worker
end
class Request
include Mongoid::Document
belongs_to :requester, class_name: "User", inverse_of: :requests
belongs_to :worker, class_name: "User", inverse_of: :assignments
end
In this example, users can both request and be assigned to tickets. In order to represent these two distinct relationships, we need to define two relations to the same model but with different names. Using inverse_of lets Mongoid know that "requests" goes with "requester" and "assignments" goes with "worker." The advantage here is twofold, we get to use meaningful names for our relation, and we can have two models related in multiple ways. Check out the Mongoid Relations documentation for more detailed information.
I am currently using has_and_belongs_to_many to implement a many-to-many relationship. I would however want to put in a attribute in the many_to_many table.
Basically I am creating a email system. I have users and conversations. A user can have many conversations and a conversations can also have many users. However, I am trying to make it so that I can have a read/unread attribute to show which messages are read. Since conversations can have many users, it is not practicable to put the attribute in the conversations table as then it would mean that the conversation is read by all. So I think it would work best in the middle table. I am wondering though how I can access that attribute in the middle table. If the attribute is read. What code do I put in to access that and how do I update the attribute. As mention above I am using has_and_belongs_to_many
If you want to have additional attributes to your has-and-belongs-to-many association, you have to build a model class for that relation. See the detailed description in the Rails Guides about it.
After having read it for myself, this is now deprecated with the current version of Rails, so you really should switch to has_many :through. Your models could be (copied and changed from the Rails Guides, I don't know if connection is a good name for the m2n relation):
class User < ActiveRecord::Base
has_many :connections
has_many :conversations, :through => :connections
end
class Connection < ActiveRecord::Base
belongs_to :user
belongs_to :conversation
end
class Conversation < ActiveRecord::Base
has_many :connections
has_many :users, :through => :connections
end
There you are able to add additional attributes to your connections table, and refer in the code to them.
I need help determining what kind of associations I should use for the following 3 models. Below are the tables and what I think the current association is. Please let me know if there is a better way to achieve below. Thanks
How the tables should look.
User Table
id
Meal Table
id
Comment Table
user_id
Meal_id
Here is what I think the associations look, but this may change depending on the type of association is used.
User
has_many :comments
Meal
has_many :comments
Comment
belongs_to :user
belongs_to :meal
That sound like a good way to do it.
I would rename the belongs_to :user association to belongs_to :author, :class_name => "User" to be more explicit about the role the association plays in your system.
If you want to add more models to comment on, you should use polymorphic associations.