How can I write a code in Ruby on rails that picks user X from my database( let say I have a column called 'taskdone' which accepts only boolean values ... And user X is true in such column) such that when a new user signs up, user X is displayed on his profile. And the new user is given a task to complete. If he
completes it successfully user X can confirm from his own account that the new user has completed his task by clicking a button which writes a value of true to the new users paid 'task done ' column. And after user X has confirmed four people, his value in the column should go back to false. It's quite complicated please I need someone to help am frustrated searching Google without answers
You can do this in two ways
1- If you need the information about "which user confirms another user" You can create an association to hold for each user X which other users he has confirmed.
2 - If you won't use these info you can just create a column that counts the number of confirmed users in the Users tabel.
In both cases, After a user confirms another user make a check if he has confirmed 4 users or not using the callback after create and then update the taskdone column.
after_create :update_task_done
In the first way do
def update_task_done
if self.confirmed_users.count == 4
self.update(taskdone: false)
end
end
In the second way
def update_task_done
if self.confirmed_users_count == 4 # notice this is column.
self.update(taskdone: false)
end
end
Related
Rails newbie so bear with me...
I created a calendar app and the owner of the calendar can add other users to the calendar. I just realized that they can add the same user many times, which obviously I don't want. I've tried a bunch of different things including methods to check inside of the model, those didn't work... I was using includes to verify...
My current method in my controller is:
def update
if #calendar.calendar_admin?(current_user)
#new_user = User.find(params[:calendar][:user_ids])
if #calendar.users.includes(#new_user)
redirect_to user_calendar_path(#calendar), notice: 'This user has already been added to this calendar.'
else
#calendar.users << #new_user
if #calendar.save
redirect_to user_calendar_path(#calendar), notice: 'Your calendar has been updated.'
else
redirect_to user_calendar_path(#calendar)
end
end
end
end
end
No matter what, it gets stuck at "this user has already been added to this calendar", even if the user hasn't. I am shoveling the new user in but I'm not even sure if that is the right manner to add the new user?
Input?
You want to use include? instead of includes.
include? returns a boolean based on whether a set contains a specific item. includes is a different method and will return a non-nil value that is truthy.
You want to test if #calendar.users already contains a specific user. Unfortunately, includes sounds right, but it is used to add a table/model to join result (if I try to run your line it explodes).
So I suggest the following alternatives:
if #calendar.users.to_a.any{|uu| uu.id == #new_user.id}
this will fetch all users in an array and check if a user exists with the same id. This is easy to understand, but not optimal since it might retrieve a lot of data.
Probably better alternative is to use the database, and count if a user with your wanted id is linked:
if #calendar.users.where("users.id" => #new_user.id).count > 0
I have an application with a series of tests (FirstTest, SecondTest etc.)
Each test has a calculation set out its relevant model that gets calculated before being saved to the database set out like this:
#first_test.rb
before_save :calculate_total
private
def calculate_total
...
end
I then have an index page for each user (welcome/index) which displays the current user's results for each test. This all works fine, however I want to work out various other things such as each users average score overall etc.
Is it possible to access the current user from the welcome model?
Currently my welcome.rb is accessing the data follows:
#welcome.rb
def self.total
FirstTest.last.total
end
This obviously access the last overall test NOT the last test from the current user.
I feel like I may have just laid the whole application out in a fairly unintelligent manner...
Thanks in advance x
Well you need to save user_id in a column for each record in FirstTest. Then you can find the total for current user
FirstTest.where(:user_id => current_user.id).last.total
Apologies in advance for the ugly code (in addition to it not working).
I have a Rails app that has many users who play different quiz games, which were created by various users. There is no rails-style association between user and quizes except that each quiz has been made by a particular user. There's actually not even a 'quiz' model in the application (quizes are made of question and answer models).
For obvious reasons, users are only allowed to try each quiz once; therefore, I have to record which users' quizers a particular user has tried. Therefore, I created a 'quiz' attribute on the user model, and serialized it, so that I would hopefully have a database column like this ['2','4','10'] if I had played the quizes that were made by users with ids 2,4 and 10.
In the user model, after creating :quiz as a 'string', I did this to turn the string into an array in the db
attr_accessible :quiz
serialize :quiz
However, I'm having a lot of trouble writing code that does all of the following
a) checks if that column's not empty (maybe the player hasn't played a quiz yet): I did player.quiz? to test that.
b) checking whether the array includes a particular user.id (i.e. if the player has already played that quiz) I do player.quiz.include?(user.id.to_s) to test that
c) creating the first entry if a user hasn't played any quizzes yet. I did quiz = user.id.to_s
d) adding to the array of game's once a user's played a second user's game (i.e. player's quiz column is ['2'] and now they play quiz by user.id 4.
With various combinations of the code below, I keep erasing/resetting the quiz column when I try to update, or I'm creating strings like '68' when I want ['6','8'] instead.
I'd be grateful if you could give me some tips to fix this up.
code not working
if player && player.quiz? && player.quiz.include?(user.id.to_s) #checks if signed in (if player), if the player.quiz column isn't empty, and if it includes a user id
alreadyplayedthisquiz = true
else
if player.quiz? #it might be that no quizzes are registered on db
quiz = player.quiz #this is a string
quiz.push(user.id.to_s) #can't push onto a string
quiz += user.id.to_s #this is wrong, because if I've played quiz 6 and 8, it'll be '68' in the db
else
quiz = user.id.to_s #if no quiz on player's db, create first one
end
alreadyplayedthisquiz = false
end
player.update_attributes({quiz: quiz})
First, I would store the values in the database as "2","4","6" rather than as ["2","4","6"]. The [ and ] are not necessary.
I would use the String#split to convert the string in the database to an array that can be used in the code. I would use Array#join to convert the array used in the code back into a string for storage in the database.
quiz = player.quiz? ? player.quiz.split(",") : []
alreadyplayedthisquiz = quiz.include? user.id.to_s
if (!alreadyplayedthisquiz)
quiz.push user.id.to_s
player.update_attributes({:quiz => quiz.join(",")})
end
I would like to add a invite code requirement for users to register in my application. I investigated the devise_invitable gem for devise and this looks very promising. However, It should not be possible to continuously invite people to the application, like devise_invitable does.
To solve the problem, I need to implant user levels in my application. I found this project on github and now I got the following idea: Once a user registers (invited by another existing user) it starts in level 1 and must complete tasks in order to archive experience points. He works his/her way up to the next level where he can invite 1 new member and then in the next level he can invite 1 other and in the next level, the user can invite 2 members, so on, so on.
I am fairy new to Ruby and I'd like to know how to encomplish this and to know if this is even possible to insert in my users controller.
Thank you for reading and have a nice day.
This should be a fairly straight forward process, as the number of invitations a user has is just an integer stored in your database. It could be something as simple as:
def level_up(level)
self.invitation_limit += level
self.save
end
While a very simple implementation, you just pass in the users level, add it to their current number of invitations, and save the user. It all really depends on how fancy you want to get, but it really comes down to basic math, and saving it to the database.
I'm not sure if this changed since the question was asked in 2012, but devise_invitable has an invitation_limit parameter:
invitation_limit: The number of invitations users can send. The default value of nil means users can send as many invites as they want, there is no limit for any user, invitation_limit column is not used. A setting of 0 means they can't send invitations. A setting n > 0 means they can send n invitations. You can change invitation_limit column for some users so they can send more or less invitations, even with global invitation_limit = 0.
You can see how this parameter is used by looking at the source here. One important part:
# Return true if this user has invitations left to send
def has_invitations_left?
if self.class.invitation_limit.present?
if invitation_limit
return invitation_limit > 0
else
return self.class.invitation_limit > 0
end
else
return true
end
end
I have a Friendship model which allows users to become friends with one another. The records for these Frienships has a requesting_user_id and an accepting_user_id. I want to build a method that checks to see that a record with the same accepting_user and requesting_user pair doesn't already exist. In short, that a one user has already befriended another user.
I started this in my User model:
def can_befriend?(accepting_user)
#accepting_user = Friendship.find_by_accepting_user_id(accepting_user)
#requesting_user = current_user
end
But I'm not sure how to check that the pair doesn't already exist. Any help?
You can actually use a dynamic cross-finder method that will search for both at the same time. It's a mouthful, but should work.
#old_friendship = Friendship.find_by_accepting_user_id_and_requesting_user_id(accepting_user.id, requesting_user.id)
if #old_friendship.nil?
#create new friendship here
end