rails activerecord - distinct counter cache implementation - ruby-on-rails

I have these tables:
broadcast
id
name
email
id
broadcast_id
user_id
subject
email_open
id
email_id
user_id
I want to keep a count of the email_open records in my broadcast table.
Is the most efficient way of doing this by having a broadcast_id in my email_open table? If it is.. then I know I can just do this in my email_open model:
belongs_to :broadcast, counter_cache: => true
Then, I add a email_open_count to my broadcast table... but I'm wondering if there's a way to do it without doing this.
Also, multiple users can have repeated records in email_open.. how do I make the count be of distinct user_id?
For example, user_id 1 can open an email 5 times but I just want the email_open_count to be 1.
Thanks

So as per your example, if user_id 1 can open an email 5 times but You just want the email_open_count to be 1.You can the same user_id to email or whichever table you want only if that user opens an email but if the user has already open don't save it again.

Related

Count total number of records in Rails join table

I have two models, users and departments, and a join table users_departments to enable a has_and_belongs_to_many association between them. I am using PostgreSQL as the database.
# users table columns
id
name
# departments table columns
id
name
# users_departments table columns
user_id
department_id
What is the best way in Rails for counting the total number of records in the users_departments table? Preferably without creating a new model class.
Please note that I do not want to count the records for a specific user or department (user.departments.count / departments.users.count), but the total number records for the table, considering all users and departments.
The best way is to just create a model called UsersDepartment and do a nice and easy query on that.
count = UsersDepartment.count
You can query the table directly however with exec_query which gives you an ActiveRecord::Result object to play with.
result = ActiveRecord::Base.connection.exec_query('select count(*) as count from users_departments')
count = result[0]['count']

authentication with join tables for multiple username or emails

I need help on devise authentication (https://github.com/heartcombo/devise) about logins.
My db design has 3 tables that need 2 joins, so it can use any of a user's emails for login, using a single password.
profiles table
id
name
emails table
profile_id - foreign key from profiles table using has many
email
users table
profile_id - foreign key from profiles table using one-to-one relationship
encrypted_password
At the moment, I can only set 1 join in conditions.
You didn't provide any details except that 2 tables have a FK to a third. So I cannot provide much detail in response. But joining all 3 is a trivial exercise. it'll come in the format of:
select
from profiles p
join emails e on e.profile_id = p.profile_id
join users u on u.profile_id = p.profile_id
where e.email = <email_address_parameter>
and encryption_routine(<password_value_parameter>) = u.encrypted_password;
Assume you have the correct model relations.
if(email = Email.find_by(email: params[:email])).present?
if(email.profile.users.where(encrypted_password: encrypt(params[:password])).count > 0)
# login success
else
# wrong password
end
else
# email not exists
end

Clean and concise way to find active records that have the same id as another set of active records

I have a table called shoppers and another table called Users. I have a shopper_id which is the foreign key in the Shoppers table and refers to the primary key id in the Users table.
I ran a query called #shoppers = shoppers.where("some condition")
This allowed me to get a set of shoppers who satisfy the condition. Next I would like to select those Users who have the same id as the shopper_id as the individual objects in #shoppers.
I know I could do this by writing a loop, but I am wondering if ruby on rails allows me to write a Users.where condition that can help me obtain the subset of user objects with the same id as shopper_id arranged in ascending order by the name field in the Users table.
Any ideas?
Try this.
#shoppers = Shopper.where("some condition")
#users = User.where(id: #shoppers.collect(&:shopper_id)).order('name asc')

friendship/follower functionality in rails

Any one have implemented a way manage to user friends(friendship in two way) and followers in database.
means what I want to achieve:
1) user1 send a connection request to user2.
2) then user2 accept user1 as friend or follower or reject it.
3) if user2 accept user1 as friend then this friendship is two way friendship.
what I am thinking to handle this:
1) I'll create a friendship table.
2) relationship column that maintain a user is follower/friend.
3) if user is friend then I'll create two entry to maintain friends relationship from both end.
Could you please suggest me best approach(gems/plugin) to handle this case.
You should create friendship with following fields
1] user_id
2] friend_id
3] status
At first when user send a request for friendship status must be Pending and when friend accept/reject the request it should be change to the Accepted/Rejected
You can create a table with columns - USER_A, USER_B, RELATION. Now, you can create a constant or enums to define the relation between USER_A and USER_B. For e.g. 0 represents no relation, 1 represents USER_A -> USER_B ( User A follows User B ), 2 represents USER_B -> USER_A ( User B follows User A ), and 3 presents USER_A <-> USER_B ( that means both way. )
You can then update the same row if you don't require history otherwise you can add one more row as the relation changes.
Hope that works!
You can check out socialization gem that provide likes, following and mentions to your ActiveRecord models.

Connecting Id field with name field

Am having a table with quetion_id , nominees and vote_count. In which the values for question_id and nominees are prepopulated from other tables with vote_count as zero.
If the users select some nominees the vote count should be incresed by one. The problem is How to connect the question_id and nominees like for this question_id this nominee is selected .
can some one give example for this situation..
I'll answer based on this scenario:
So you have a...
1) User
who can...
2) Vote
for a...
3) Nominee
And it's a given that MANY users can vote for MANY nominees.
You probably aready have tblUser and tblNominee - so you need a link table that can contain the votes (tblUserNomineeVote).
tblUserNomineeVote has fields for UserId and NomineeId, and therefore registers a vote. You may need to add constraints depending on how many votes a user can register etc.
You can then use:
SELECT
tblNominee.Name,
COUNT(*)
FROM
tblNominee
INNER JOIN
tblUserNomineeVote ON tblUserNomnieeVote.NomineeId = tblNominee.NomineeId
GROUP BY
tblNominee.Name

Resources