I use this logic in my app:
controller
#current_user = User.find_or_create_from_oauth(auth_hash)
user.rb
def self.find_or_create_from_oauth(auth_hash)
provider = auth_hash["provider"]
uid = auth_hash["uid"].to_s
case provider
when 'twitter'
if user = self.find_by_twitter_uid(uid)
return user
else
return self.create_user_from_twitter(auth_hash)
end
end
end
def self.create_user_from_twitter(auth_hash)
a = self.create({
:twitter_uid => auth_hash["uid"],
:name => auth_hash["info"]["name"]
})
puts a.inspect
user = User.find_by_twitter_uid(a.twitter_uid)
puts '---'
puts user.inspect
end
Immediately after self.create I would need to run this line:
Assignment.create(:user_id => a.id, :role_id => 2)
The problem is, that the line puts user.inspect return something like this:
#<User id: nil, name: "...name...", twitter_uid: "96580821", provider: "twitter", created_at: nil, updated_at: nil>
Why is in the hash returned id: nil?
Or, is there any other way, how to get the ID of last created record?
If the user has been correctly saved, you can use directly a:
a.assignments.create(:role_id => 2)
Otherwise (check using create! instead of create) there may be a validation error.
Related
I want to get data(customer ID) from the Stripe webhook then save it to my db, I get the data but the problem is customer_id is still nil on my db. Here's my code
StripeEvent.configure do |events|
events.all do |event|
if event.type == 'customer.created'
customer = event.data.object
user = User.where('customer_id LIKE ?', "%#{customer['id']}%").first
if user
customer = Stripe::Customer.retrieve(JSON.parse(user.customer_id)['id'])
user.customer_id = customer.to_json
user.save!
end
end
end
end
This code :
user = User.where('customer_id LIKE ?', "%#{customer['id']}%").first
gives this output:
SELECT "users".* FROM "users" WHERE (customer_id LIKE '%cus_EEIReNX3M4je2U%') ORDER BY "users"."id" ASC LIMIT
And when I get to my db, my customer_id field is still nil, here's the output:
<User id: 3, email: "achielinda44#yahoo.com", created_at: "2018-12-27 03:47:41", updated_at: "2018-12-27 03:47:41", first_name: "Achie", last_name: nil, gender: nil, gender_preferences: nil, description: "trial stripe", photo: nil, provider: nil, uid: nil, name: nil, image: nil, customer_id: nil>
Can anyone please see something that I'm missing out on? I will really appreciate the help. Thanks!
My code was all wrong, not all though. The user object was nil because I was trying to get a customer_id that was not yet available, so I got the user using email, then passed the stripe customer id to them then finally saved them. It worked!
StripeEvent.configure do |events|
events.all do |event|
if event.type == 'customer.created'
customer = event.data.object
user = User.find_by(email: customer.email)
if user
user.customer_id = customer.id
user.save!
end
end
end
Trying to test if making a Vote on an Answer updates its score.
The score updates but its not the same object that gets tested.
( Every Vote has its own voteable Answer object, with same .id)
Therefore the spec fails.
PRY console during rspec testing:
> Answer.first
=> #<Answer:0x000000087b6418 id: 1, (...) score: 2>
> answer
=> #<Answer:0x000000081bea88 id: 1, (...) score: 0>
vote_spec.rb
answer ||= FactoryGirl.create(:answer)
vote = FactoryGirl.create(:vote, like: true, user_id: 1, voteable_id: answer.id, voteable_type: "Answer")
vote2 = FactoryGirl.create(:vote, like: true, user_id: 2, voteable_id: answer.id, voteable_type: "Answer")
vote3 = FactoryGirl.create(:vote, like: true, user_id: 3, voteable_id: answer.id, voteable_type: "Answer")
vote4 = FactoryGirl.create(:vote, user_id: 4, voteable_id: answer.id, voteable_type: "Answer")
expect(answer.score).to eq(2)
vote.rb
after_create :set_voteable_score
private
def set_voteable_score
self.voteable.update_column(:score, count_score(self.voteable))
true
binding.pry
end
def count_score(voteable)
votes = voteable.votes.all
votes.where(like: true).count - votes.where(like: false).count
end
So if I check the vote.voteable.score with all vote(vote, vote2, vote3...), each returns a different voteable object, and the answer in vote_spec.rb doesn't get updated.
Why is this behaviour ( more than 1 record with same id exists)?
If all the voteables have the same id, they're all the same records. What you have then, probably, is different instances of the record, which have been loaded from the db at different times.
Try this:
expect(answer.reload.score).to eq(2)
So in my wiki model I have an attribute for private. If private is true then the wiki should not be viewable to users who are not assign to the wiki_ids via a HABTM relationship.
wiki.rb:
class Wiki
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :users
field :title, type: String
field :body, type: String
field :private, type: Boolean, default: false
scope :visible_to, ->(user) {
user.present? || user.blank? ?
where(:private => false) : where(:private => false).or(:id => user.wiki_ids)
}
def public?
!self.private?
end
end
WikisController:
def index
##wikis = policy_scope(Wiki)
##wikis = Wiki.all
#wikis = Wiki.visible_to(current_user)
authorize #wikis
end
def show
#wiki = Wiki.find(params[:id])
end
def new
#wiki = Wiki.new
authorize #wiki
end
def create
#wiki = current_user.wikis.build(params.require(:wiki).permit(:title, :body, :private, :user))
authorize #wiki
if #wiki.save
flash[:notice] = "Wiki was saved."
redirect_to #wiki
# report success
else
flash[:error] = "There was an error saving your wiki. Please try again."
render :new
end
I'm pretty confident its the scope that needs to be modified in the model, because if i comment out the scope in the model and replace the index in the controler to Wiki.all. I see all the wikis.
As of right now as somebody who created the wiki plus flagged it private and I am logged in I do not see that wiki nor does anybody that I add as a user to the wiki.
I tried adding other conditions to the end such as user.present? ? where(:id => user.wiki_ids) and user.present? && where(:id => user.wiki_ids) but just get errors thrown back at me.
DB entry for User:
User_id: 547eb8867261691268000000, wiki_ids: [BSON::ObjectId('54807226726 1690be0260000'),
BSON::ObjectId('5480735c7261690bae000000'), BSON::ObjectId('548
136e57261690aef000000'), BSON::ObjectId('5489af337261690d95000000'),
BSON::Objec tId('5489b57e7261690d95010000'),
BSON::ObjectId('548f9f607261690bb5060000'), BSO
N::ObjectId('54908f127261690be8000000'),
BSON::ObjectId('54908f207261690be801000 0')], name: "Carey VonRueden",
email: "admin#email.com", encrypted_password: "$2a
$10$NrlQ2XH64UucOPcI1aje9.57eoSO74676264YrIjfGvncyGcpGWy",
reset_password_token : nil, reset_password_sent_at: nil,
remember_created_at: nil, sign_in_count: 7, current_sign_in_at:
2014-12-17 18:51:15 UTC, last_sign_in_at: 2014-12-16 02:38:5 8 UTC,
current_sign_in_ip: "10.0.2.2", last_sign_in_ip: "10.0.2.2",
confirmation
_token: nil, confirmed_at: 2014-12-03 07:15:18 UTC, confirmation_sent_at: nil, u nconfirmed_email: nil, role: "admin">
DB entry for Wiki:
Wiki _id: 54908f207261690be8010000, created_at: 2014-12-16 19:59:28 UTC, updated_at: 2014-12-16 19:59:28 UTC, user_ids:
[BSON::ObjectId('547eb886726169126 8000000')], title: "Private", body:
"Private", private: true>
your scope condition is wrong
user.present? || user.blank? -> this will be true always. if user is present or user is blank, it will always return only the public wikis
Change your scope to something like below.(assuming you want all public wiki's if user is not signed in. If user is signed in, you want public + the wikis created by user)
scope :visible_to, ->(user) {
user.nil? ? where(:private => false) : where(:private => false).or(:id => user.wiki_ids)
}
If you are still not getting what you are expecting, check if user.wiki_ids is returning the right values
I'm new to RSpec so I'm looking for a little help on a simple test:
# controller method
def show
#group = Group.find(params[:id])
#group_members = #group.group_members.order("posts ASC")
end
# in my rspec
it "should show order correctly" do
#group = FactoryGirl.create(:group)
#user_1 = FactoryGirl.create(:user, user_name: "Gary")
#user_2 = FactoryGirl.create(:user, user_name: "Shawn")
#user_3 = FactoryGirl.create(:user, user_name: "Gus")
#user_4 = FactoryGirl.create(:user, user_name: "Jack")
#group_member_1 = FactoryGirl.create(:group_member, group_id: #group.id, user_id: #user_1.id, posts: 30)
#group_member_2 = FactoryGirl.create(:group_member, group_id: #group.id, user_id: #user_2.id, posts: 20)
#group_member_3 = FactoryGirl.create(:group_member, group_id: #group.id, user_id: #user_3.id, posts: 10)
#group_member_4 = FactoryGirl.create(:group_member, group_id: #group.id, user_id: #user_4.id, posts: 15)
visit group_path(#group)
# how do i assert the order of the array?
end
Can someone please help me with a statement to check that the array sorted correctly?
my_array.should eq expected_array
That will make sure that each item is in the exact same spot. If you want to check that an array has the same elements as another array, but the order doesn't matter, do this:
my_array.should =~ expected_array
So in your particular case, you first would need to do a get to the show action, then check the variable. That's done like this:
get :show, :id => #group.id
expected_group_members = [#group_member_3, #group_member_4, #group_member_2, #group_member_1]
assigns(:group_members).should eq expected_group_members
For more information, check out RSpec's GitHub page.
I have this method
def last_board
user = current_user #current_user
boards = current_user.boards #return every boards that belongs to current_user e.g. [#<Board _id: 4f2968ac1d41c81c7c000063, _type: "Board", created_at...]
followers = user.all_followers #return every followers of user [#<User _id: 4f2862b21d41c847e200005b, _type: "User" reset_password_sent_at: nil, confirmation_token: nil,...]
followers.each do |follower|
boards.each do |board|
# I want to be a follower of user, if I am following at least one board of this user
#I want run this code, "follower.unfollow(user)", only if follower does not following any user's board.
#this method "follower.follower_of?(board)" return true or false if follower follow board
end
end
you can something like this
followers.each do |follower|
is_having_any_board = false
follower.boards.each do |follower_board|
boards.each do |board|
if(follower_board.id == board.id)#delete last )
is_having_any_board = true
break;
end
end
end
if(is_having_any_board)
follower.follow(user)
else
follower.unfollow(user)
end
end