i have an application am designing which consists of users making friends and users
having many posts, paintings, friends and talks
the model is below
class User < ActiveRecord::Base
has_many :paintings, :dependent => :destroy
has_many :sells, :dependent => :destroy
has_many :posts, :dependent => :destroy
has_many :talks, :dependent => :destroy
has_many :friends
has_many :comments
end
i have set a notification system in which when a user creates a post or painting e.t.c
a notification is sent to the users friends which i have achieved with public_activity gem,
what i intend to achieve is a notification system in which when the notification is created, every user involved can mark as seen i.e they have seen it so THAT notification is not shown to the user anymore... And also when a user comments on a notification, i want a notification to be sent to the owner of the activity, and any other user that comments on THAT notification... IN SUMMARY, I NEED A FACEBOOK LIKE NOTIFACATION SYSTEM...
Have you considered creating a Notification after the relevant post/painting has been added?
Notifications would be created (probably using an after_create action on each of the relevant models e.g. posts, paintings).
class Post < ActiveRecord::Base
after_create :create_notification
private
def create_notification
# create notification here
end
end
If there are lots of notifications to be created then you may wish to consider creating them in a background job.
A notification would belong to the target friend of the user and could therefore be marked as seen through an attribute on the notification. You would include instance methods on the notification object to deal with this.
class Notification < ActiveRecord::Base
belongs_to :user # friend of the originating user
def mark_seen
update_attributes(viewed: true)
end
end
You could also add scopes on the notifications to make sure that users can easily see unseen notifications.
class User < ActiveRecord::Base
has_many :notifications
has_many :unseen_notifications, conditions: "notifications.viewed IS false" #or something like that
end
Hope this helps to set you on the right track.
Related
I am trying to learn to model SQL databases, and am having some trouble understanding some concepts. I want to a build an app, where users can split a bill at a restaurant. Could someone please tell me if the following is allowed?
I have Bills, Items, and Users
Bill has_many :items, dependent: :destroy
Bill has_many :users, foreign_key: :user_id
User has_many :bills, foreign_key: :created_by
Item belongs_to :bill
Is it ok for a user to have many bills, and a bill to have many users?
This is a more fundamental database design issue. If I were to design this database for a bill sharing app, it would be like this
user.rb
has_many :bill_contributions
has_many :bills, through: :bill_contributions
bill.rb
has_many :items
has_many :bill_contributions
has_many :users, through: :bill_contributions
bill_contribution.rb
belongs_to :user
belongs_to :bill
I split it like this because there is a has many and belongs to many relationship between the user and bills as a user can have a lot of bills and bills can be split among many users. you can look up HABTM
database relationships if you wish to learn more
in a Rails 3 application there are two models assinged to each other by belongs_to and has_one. On both sides there is :depended => :destroy configured for this association.
now I had to add a :before_destroy callback in one of these models. the problem is now that this callback is triggered twice when an entity which includes this callback is destroyed. When I remove :depended => :destroy in the other model, it's triggered only once. So it seems this i causing the problem.
is there an elegant way to fix this ?
:dependent
Controls what happens to the associated objects when their owner is destroyed
dependent destroy must be alone in a model
has_many :comments, dependent: :destroy
has_one :position, dependent: :destroy
Sorry for my english XD
I'm currently building a rails application that contains 3 user types. This is my first experience with web development, and I would like to avoid making crucial design errors that will cost me later on. Hopefully more experienced rails users and web developers will be able to guide me in the right direction.
I want to use Devise as my primary authentication system, and I am currently planning something like this in order to support 3 user-types within the Devise framework:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
belongs_to :rolable, :polymorphic => true
end
For each of the three user-types:
# usertype1.rb
class UserType1 < ActiveRecord::Base
has_one :user, :as => :rolable
end
# usertype2.rb
class UserType2 < ActiveRecord::Base
has_one :user, :as => :rolable
end
Essentially, there is a polymorphic association between the user class and the several different user types. My hope is that this approach will allow me to eventually add different associative keywords within the user-type models (such as has-many) that will allow convenient querying of the database.
I'm also concerned about how to implement user-dependent routing. The idea is that each user-type will see a separate "hub" when they log-in, with different dashboards, different actions, etc. I was thinking that I would approach this by overriding the Devise SessionsController. Something like this:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
if user.type == 1
redirect_to hub_typeone
else if user.type == 2
redirect_to hub_typetwo
else
redirect_to hub_typethree
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
The idea is that upon successful authentication, the user is routed to a different page based on user type. I'm planning on using the devise current_user framework to then query the database to populate the hubs with the user-specific data.
Do you guys have any pointers for me? Do you see any huge flaws in my plans/reasoning/approach? Thanks in advance!
I get a feeling you are over-engineering this, and building something You Aren't Gonna Need It
It's best if you are clear about what the three different user types are. Most applications would require the following three user types:
Guest users, who aren't logged in, and can access some part of the application
Regular users
Admin users who administer the rights of regular users.
I am curious to know what other user types you would need if they are not in this list.
Devise wikipages has suggestions on how to create a guest user, and how to add an admin role. Probably best to start by implementing the functionality of the regular users of your application, and then use the above mentioned resources to add other user types.
I have just added devise_invitable to an app with a working implementation of devise already in place.
The invitation process itself all works fine (email is sent, new user can click link and set password etc).
The problem is that the inviter, a User, has an associated Profile, which is deleted when the inviter hits the 'Send an invitation' button.
Anyone have any idea why the invitation process would nuke an associated object on the inviter? I am going to try to trace this through the devise_invitable code, but it would be good to know if anyone has had this problem before, or knows where in devise's code the problem might lie.
The User:
has_one :profile, :inverse_of => :user, :dependent => :destroy
The Profile
belongs_to :user, :inverse_of => :profile
The error here is because – by default – devise_invitable's after_invite_path_for simply calls after_sign_in_path_for.
However, it does not pass the current user as the resource, which would be the case with a regular sign in.
If you override after_sign_in_path_for assuming it will only be called after a genuine sign in, as I did, this can be confusing.
(In my particular case: what my overridden method did was to look for the resource's associated profile, and if it didn't have one it would make a new one assuming the user is logging in for the first time. When devise_invitable passed an unexpected resource, this new profile object would overwrite the existing association and the :dependent => :destroy callback would be triggered on the old profile object. D'oh!)
I am designing a website which has many users, each user has many posts, and each post has many photos. Because I hope user can preview the upload photos when they are creating new post, I found the answer here, which suggested using a subform to upload photos.
I use carrierwaves to handle photo upload, and jquery-file-upload for user interface. The models are:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
attr_accessible :title, :description, :photo_ids
belongs_to :user
has_many :photos, :dependent => :destroy
end
class Photo < ActiveRecord::Base
mount_uploader :image, ImageUploader
attr_accessible :image
belongs_to :post
end
In the new post view, I put a jquery-file-upload UI above the normal post form, then:
When user select a photo, it will be uploaded to PhotosController via jquery-file-upload api. The post_id for this photo is nil at this step.
After photo uploaded finished, I use javascript to add a hidden input form like this:
input type="hidden" id="collection_image_ids" name="collection[collection_image_ids][]" value=#{the id of the photo}
User can repeat step 1&2 many times, then submit the post.
Everything works well, however....
I don't think it's a good idea to allow mass assignment for photo_ids because someone can use this request to assign other user's photo to his post. (in edit view)
The reference answer suggested using some randomized access key to improve the security,
but when someone visit other user's post, he can still get the randomized access key of those photos, right?
So the implementation is not safe for now right?
Could anyone give me some suggestions or what is the proper way to handle this problem?