I am pretty sure this is a pretty basic question. anyway I don't find the right information to get going.
I have got 3 models.
Users - Tasks - Notes
Users and Tasks are on the same level, as tasks are children of the Projects model, and they function as a template.
Then for each user I display all the tasks of the project and add notes.
Notes in this case are children of BOTH Users and Tasks, actually they are children of the combination of the two.
What is the best way to tackle this problem? I checked out polymorphic associations and doesn't seem it will work in this case.
Cheers,
Davide
From what I understand of your problem polymorphic associations are exactly what you want, being that Users have many Notes, and Tasks have many Notes.
The relationships would look like this
in both user.rb and task.rb
has_many :notes, :as => :noteable
in note.rb
belongs_to :noteable, :polymorphic => true
in your create notes migration
t.references :noteable, :polymorphic => true
Note both Users and Tasks can have Notes, and Notes can belong to either a User or a Task (or anything else that connects using the noteable polymorphic interface).
Related
I have a problem. I need to set a model of report_templates unique in my database in relation to the classroom, each classroom has only one report_template.
But in my DB, I already have a classroom with multiple report_templates.
is it safe to add this validation to report_template model upload to staging?
There are two approaches:-
If you add validation then you will get error when you are editing existing report templates. This is because validations are called when you save the record. So you might have to remove the duplicate/multiple records manually via console or db or a rake task.
Simply accessing the record will not throw an error.
If one classroom has only report template do you think it is better to use either of below? I do not know the exact scenario so cannot suggest an approach.
has_one association
belongs_to association
Thank you.
I've a problem with a couple of polymorphic associations. I'm trying to connect both Users and Recipes to shared Dietary Requirements (DRs) through polymorphic associations, with the dietary requirements available to many-to-many of each.
I've created a Dietary Requirement to test this (Vegetarian), though am having trouble accessing this in the page view. I think the reason for this is that the DR created has the classifiable_type Recipe, meaning when the database query runs, I can't access this particular instance for my Users as SQLite automatically looks for a classifiable_type of User. Also, as it stands, each DR appears to have to belong to a specific User or Recipe, while I'd like them all available to many (or am I wrong here?)
In the console, I can see both User.first.dietary_requirements and Recipe.first.dietary_requirements, though in the view I can't access these, because of the reasons above.
Is there a way to circumvent this problem and get my view showing a list of User DRs and Recipe DRs, or will I have to adjust my models to achieve this? Right now I'm planning to switch to more verbose has-many-through relationships, with separate join tables between User - DRs and Recipe - DRs. If there's an alternative, Rails-way to achieve this, it'd be great to hear.
Model code below:
Recipe
has_many :dietary_requirements, as: :classifiable
User
has_many :dietary_requirements, as: :classifiable
Dietary Requirement
belongs_to :classifiable, polymorphic: true
You would need Dietary Requirement to have has_and_belongs_to_many relationship with Users and Recipes, however you cannot have polymorphic HABTM associations. You will need to create a join model for it to work.
More: HABTM Polymorphic Relationship
It's been a while since I've used a join table so I'm looking to refresh my memory on best practice usage.
I have a Rails 3.2.19 app that has a Unit model and I will be adding a Maintenance model. The idea is to create a resource to add maintenance records for each unit. So for instance when the tires are rotated or the oil is changed a maintenance record is created and the unit is assigned to that maintenance record.
I'd like to be able to iterate over each maintenance record in a view, displaying the unit name, type of maintenance, and details of what maintenance was performed.
I'm unsure of the best way to do this via associations. Here was my initial thought:
unit.rb
has_many :maintenances
maintenance.rb
attr_accessible :unit_id
belongs_to :unit
That should allow me to iterate over each maintenance object and display the records for a particular unit. But something doesn't seem right. I'm wondering if I need to setup a join table and do a has_many :through like this.
unit.rb
has_many :unit_maintenances
has_many :maintenances, through: :unit_maintenances
maintenance.rb
has_many :unit_maintenances
has_many :units, through: :unit_maintenances
unit_maintenance.rb
attr_accessible :maintenance_id, :unit_id
belongs_to :maintenance
belongs_to :unit
I am a bit unsure if I'm going overboard here and if I even need a join table considering there will be multiple maintenance records each with one unit assigned to it. I'm thinking that a basic has_many and belongs_to association will work but I'm also wondering if I need to do a join table at all.
I'd also like to be able to see all maintenance records by truck, search by truck in the view, and also setup alerts if a certain threshold is met (like oil_change_mileage is > 5000).
If I can clarify what I'm trying to do here, please let me know. But basically I'm setting up maintenance records for each unit so we can keep a record of what was done and hopefully build it up into something a bit more robust.
I'm using Rails 3 and Devise 2.0
In the index view of the Posts resource, I want to display a vote button unless the current_user has already voted.
I am only passing in #posts = Post.all into the index view. What's the best way to check each post to see if the current_user has already voted and render the view accordingly?
I'm currently trying to do this by having a voted? method in my Post model, but the current_user method is not available there.
The other solution I see is to have if letter.votes.find_by_user_id(current_user.id) in the index view, but I'm not sure if this belongs in view logic.
One good solution would be to implement a method in your Post model or a helper as follows (assuming post has_many votes):
def voted?(user)
!votes.find_by_user_id(user.id).empty?
end
Then, in your view you can put if post.voted?(current_user)
You are right, the logic belongs in the model, and the model does not have any knowledge (nor should it) of anything outside the model, such as the current user. You have to pass it in as an argument
You have a Post, a Vote and a User model
And you want to know when a post has a vote from a specific user
One way to do it could be Justin's method, but that will produce way too many database queries than needed
A better solution would be to use a has_many :through association like this:
class Post
has_many :votes
has_many :voted_users, through: :votes, source: :user
end
And now you can call #posts = Post.includes(:voted_users)
This will eager load all the users that voted on each post
And you could just say
if post.voted_users.include? current_user
#do stuff
end
If you have the following models:
client has_many :projects
project has_many :tasks
tasks has_many :timeentries
and
timeentries belongs_to :task
task belongs_to :project
project belongs_to :client
Then do you need model statements like:
timeentries belongs_to project :through => :tasks
client has_many :tasks, :through => :projects
Thanks
The simple answer is that you don't have to, but you might want to. It depends a bit how you are going to use your model- if you want to be able to access each end of the relationship from the other then you might need it. So if you wanted to be able to access Project directly from TimeEntries.Project then you might want it, if you are happy to go through TimeEntries.Task.Project then you don't need the explicit relationship, which can complicate matters further on.
Be aware of Has_and_belongs_to_many :through which is for cases where you have a many-to-many relationship using an intermediary table purely to represent the relationship so the intermediary doesn't need it's own model.
This is quite common in two-way many-to-many relationships- supposing you have a tag cloud of some kind you might have something like this:
Article ArticleTag Tag
Id ArticleId Id
Title TagId Text
Text
There one article can have many tags, one tag can be applied to many articles, so you don't want to bind either in the table. So the Article has_many Tags through ArticleTag.
This gives a handy summary of associations in Rails.