How would I set up this functionality? - ruby-on-rails

I want to have a text field on a photo show view with autocomplete suggesting users. When someone selects a user from the suggestion list, the photo is posted to the selected user's profile.
I understand how to set up autocomplete, but how should I structure the display of the images onto the selected user's profile? Would this require a new model? Perhaps polymorphic if I want it to let users do this with multiple resources?

Can a photo be posted to multiple users' profiles? If so, then I would use the "has_many through" functionality that Rails offers for many-to-many relationships.
class User < ActiveRecord::Base
has_many :posted_photos
has_many :photos, :through => :posted_photos
end
class Photo < ActiveRecord::Base
has_many :posted_photos
has_many :users, :through => :posted_photos
end
class PostedPhoto < ActiveRecord::Base
has_many :users
has_many :photos
end
So you end up with a table of users, a table of photos and a table which joins the two.
See this blog post for a good explanation of Rails associations.

Related

Ruby on Rails has_many :through in a polymorphic association

I have searched and searched and found only partial solutions to my current question.
The thing is, I'd like to know if it is possible to use has_many :through along with a polymorphic association in Ruby on Rails.
I have a system where students can create travel plans (that can belong to many students) and refund claims (that can belong to only one student) for their projects. In this system, both admin users and students are able to comment on the plans and claims.
My associations are:
class Student < ActiveRecord::Base
has_and_belongs_to_many :travel_plans
has_many :refund_claims
has_many :comments, through: :travel_plans
has_many :comments, through: :refund_claims
end
class AdminUser < ActiveRecord::Base
has_many :comments
end
class TravelPlan < ActiveRecord::Base
has_and_belongs_to_many :students
has_many :comments, as: :commentable
end
class RefundClaim < ActiveRecord::Base
belongs_to :student
has_many :comments, as: :commentable
end
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
My questions are:
Is it correct to associate comments twice in the Student model?
I don't want the AdminUsers to have travel plans and refund claims, how can I identify their comments as being made on a travel plan or on a refund claim?
Would there be a better approach?
Thanks a lot in advance for everyone!
Cheers,
You probably want to add an polymorphic author attribute to the Comment model. Than you just need has_many :comments, as: :author to the Student and AdminUser model.
If this is a new application and you are starting on the green field you might want to rethink your models a bit and add a Role and a User model. Student would than be a role of user as would AdminUser be.
Is it correct to associate comments twice in the Student model?
No, not really. If you have duplicate association name, you can only use one of them. If you want to use both, you have to name them differently.

Invite users to groups rails app

I'm building a simple rails app that allows users to login and create private lists for themselves, so far so good. I would like the user to then have the option to invite people to a certain list where these new users would have edit access to the tasks. This would be in the same vein as basecamp and trello in regards to adding users.
Where would I begin to start with this I have been wracking my brains and searching google and can't find any relevant tutorials of guidance.
Ok, so what about having
1) A users Table (model)
2) A lists table (model)
Model Associations
A user has many lists
A list belongs to a user
User table will have Foreign Key list_id (you will need to add this via a migration)
Thats just a start, I am assuming you know about resources ( the big 7 ) in rails? As you will be using this extensively
You can create a Membership table which will act as a join table between a User and List. You can then add an :admin attribute to the Membership model with a boolean type.
class List < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
class User < ActiveRecord::Base
has_many :memberships
has_many :lists, :through => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :list
end

How to create a rating system for has_many - has_and_belongs_to_many relation in Rails

I have an app where:
User has_many Openings
Opening belongs to User & has_and_belongs_to_many Categories
Category has_and_belongs_to_many Openings
I'm trying to create a rating system where the user rates each opening per category, and am struggling to see what relations I need where. Could anyone help point me in the right direction please?
Basically I want the rating to belong to a opening_category relation.
Instead of using has_and_belongs_to_many association, you want the has_many through relation
Thus, you create a new model
class OpeningCategory
belongs_to :opening
belongs_to :category
end
Then you can use Opening has_many :categories, :through => :opening_categories, and Category has_many :openings, :through => :opening_categories.
Your rating can be done with the OpeningCategory, whether that is an average rating column, or a separate Rating model which :belongs_to :opening_categories.

Rails: Should I use has_many :through?

I'm trying to figure out how to best way to create associations for the following models:
User
Category
Post
Comments
Here are the requirements I'm trying to meet:
A user can have many posts
A post belongs to a user
A post can have many comments
A comment belongs to a post
A post can belong to a category
A user does NOT have many categories.
(The number of categories is fixed and the same for all users)
A category can have many posts
In terms of routing, I'd like to be able to access a post within a certain category for a specific user. For example:
http://domain.com/users/1/categories/1/posts
Since there is no direct relationship between User and Category, I'm not quite sure how to best set up the associations. And I'm totally lost on how to configure the routes.
Here's what I have for my models:
class User < ActiveRecord::Base
has_many :posts
end
class Category < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :metric
has_many :comments
end
class Comments < ActiveRecord::Base
belongs_to :post
end
Is this a case where I should be using has_many :through relationships? Or something more complex like polymorphic associations? Thanks in advance!
Yes, it would be a very good idea to use :
User has_many :comments, :through => :posts
If you like, you can also get categories comments, by :
Category has_many :comments, :through => :posts
Remember that a through association is just a facility that allows you to do things like user.comments directly (and through is the way for the association to find the user comment that is referred to post model).

Rails modeling for a user

When building a rails app that allows a User to login and create data, is it best to setup a belongs_to :user association on every single model? For example, let's say a user can create Favorites, Colors and Tags.
And let's say Favorites has_many :tags and Colors also has_many :tags. Is it still important for Tags to belong_to :user assuming the User is the only person who has authority to edit those tags?
And a similar question along the same lines: When updating data in FavoritesController, I've come to the conclusion that you perform CRUD operations by always doing something like current_user.favorites.find(param[:id].update_attributes(param[:favorite]) so that they can definitely only update models that belong to them. Right?
Update Wasn't too happy with any of the answers, as no one really answered my question but instead went after the for-example-only Tags model suggesting better ways to do that. I'm assuming I was right, and models should belong_to :user. I also discovered some great security tips that address my questions here: http://asciicasts.com/episodes/178-seven-security-tips
As you describe the tags it seems that they are more of an aspect, so you can implement them as a polymorphic association. But you should do it many-to-many, as tags can be reused among users and taggable objects. Let's call the join model Tagging, which will be the one that belongs to user if you want to remember who created the tagging.
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :colors, :through => :taggings, :source => :taggable, :source_type => "Color"
has_many :favorites, :through => :taggings, :source => :taggable, :source_type => "Favorite"
end
class Tagging < ActiveRecord::Base
belongs_to :user
belongs_to :taggable, :polymorphic => true
belongs_to :tag
end
class Color < ActiveRecord::Base
belongs_to :user
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class Favorite < ActiveRecord::Base
belongs_to :user
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class User < ActiveRecord::Base
has_many :favorites
has_many :colors
has_many :taggings
has_many :tags, :through => :taggings
end
As for the Favorite updating, I agree with you: you will mostly work within the scope of a user (most likely the currently logged in user).
It depends on your model. Both cases are valid but I'd discorage making a circular relationships like that. Having a hierarchy is more flexible. For example: User->Favorites->Tags (unless you want to tag users as well)
User.favorites.find(params[:id]).update_attributes(param[:favorite])
is what you mean I guess (syntax). Whoever calls the URL will perform that action. Dont rely on the fact that that URL is visible to one user only (owner of the favorite). You should have checks in place that the currently logged in user is the only one performing actions on the objects that belong to him.
The proposed mechanism sounds a bit too complex for me. I prefer the current_user way. Assume there is a current_user (following the authlogic way) in your authentication system, then simple add a user references (user_id) in every relevant table. Update the current_user for new or update record via a controller filter.
In the models, put relevant belongs_to :users accordingly, put enough has_many in users model if needed.
:has_many and :belongs_to in AR will explains the relationship between models, but not necessarily you have to use them in your models, the associaton between them will be already present in the tables as a foreign key.
But adding :has_many or :belongs_to to your models will give you extra methods to your model
ex:
class User < ActiveRecord::Base
has_many :favorites
#def favorites
# Favorite.find_all_by_user_id(self.id)
# end
end
If you mention has_many it will give a new method in your model called favorites, that method will be invisible (will be present in the AR).
Similarly for any association, if you are planning to use this kind of methods you should use associations in your models.

Resources