Rails - How to Provide Notifications to Users About Some Events

I have a problem in the rails. Im actually solving this, but I guess theres an easier way there.

I got user models / members / groups and user models / invitations / events. Membership joins the user and the group. The invitation joins the user and the event.

The membership and invitation model is the same. A group and an event have several identical columns. The membership / invitation model has a logical โ€œacceptedโ€ column, that is, the user invited to the group / event must accept this invitation before he becomes a participant / participant.

Now, if the user subscribes in all groups, invitations should appear in the list. In fact, I want to add even more notifications to the system, and the events are not yet included in mine.

My solution is to add a notification model owned by the user. Therefore, each user has many notifications. In addition, this model is polymorphic and refers to membership and invitation.

#user model class User < ActiveRecord::Base has_many :memberships, :dependent => :destroy has_many :groups, :through => :memberships has_many :invitations, :dependent => :destroy has_many :events, :through => invitations has_many :notifications #membership model (equal to invitation model) class Membership < ActiveRecord::Base belongs_to :user belongs_to :group has_one :notifications, :as => :noticeable #group model (equal to event model but participants for members and invitation for membership) class Group < ActiveRecord::Base has_many :memberships has_many :users, :through => :memberships has_many :members, :through => :memberships, :source => :user, :conditions => ['memberships.accepted = ?', true] #notification model class Notification < ActiveRecord::Base belongs_to :user belongs_to :noticeable, :polymorphic => true 

I added some data to the database, and Im tested them on the console

 myUser = User.find(6) # will be exchanged with current_user in the actual program 

I will run all notifications with each of them ... but first I check all further actions with one notification

 myNotice = myUser.notifications.first 

whether visible_type of myNotices is a membership or an invitation, I will show it as a notification about a group or event in this case noticeable_type = membership

 myGroup = Group.find(Membership.find(myNotice.noticeable_id).group_id) 

-> Do you want to join the group "myGroup.name"? Yes | No

On Yes: Membership.find(myNotice.noticeable_id).accepted = true

On No: Membership.find(myNotice.noticeable_id).destroy

And: myNotice.destroy

This is my idea. Is this a way to solve the problem?

"Each of them," which goes through all the notifications, will be in the view file. This means that "Group.find (Membership.find (myNotice.noticeable_id) .group_id)" must be in the views file or partially. Isn't that ugly?

I think I used a lot of โ€œfindsโ€, which means a lot of SQL queries. Isn't there a way to reduce them with some kind of "Ruby on Rails" -magic?

Thanks:)

+4
source share
2 answers

Finally, I found how to solve this! I ran into this problem again and was looking for "reverse polymorphic." I found the following message: https://gist.github.com/runemadsen/1242485

Polymorphic associations are inverted. It's pretty easy to make polymorphic associations in Rails: A Picture can belong to either BlogPost or an article. But what if you need a relationship the other way around? Image, text, and video can belong to an article, and this article can find the whole @ article.media call. This example shows how to create an ArticleElement join model that processes polymorphic relationships. To add fields common to all polymorphic models, add fields to the join model.

  class Article < ActiveRecord::Base has_many :article_elements has_many :pictures, :through => :article_elements, :source => :element, :source_type => 'Picture' has_many :videos, :through => :article_elements, :source => :element, :source_type => 'Video' end class Picture < ActiveRecord::Base has_one :article_element, :as =>:element has_one :article, :through => :article_elements end class Video < ActiveRecord::Base has_one :article_element, :as =>:element has_one :article, :through => :article_elements end class ArticleElement < ActiveRecord::Base belongs_to :article belongs_to :element, :polymorphic => true end t = Article.new t.article_elements # [] p = Picture.new t.article_elements.create(:element => p) t.article_elements # [<ArticleElement id: 1, article_id: 1, element_id: 1, element_type: "Picture", created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">] t.pictures # [#<Picture id: 1, created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">] 
0
source

Something similar is needed for my application, so we are updating the answer here if someone finds this useful.

  #user model has_many :membership_notices, :through => :notifications, :source => :membership, :conditions => {"notifications.noticeable_type" => "membership"} has_many :event_notices, :through => :notifications, :source => :event ,:conditions => {"notifications.noticeable_type" => "event"} 

Notifications are now available as

  user.membership_notices user.event_notices 
+1
source

All Articles