undefined method id for TrueClass Rails - ruby-on-rails-3

def can_save(board,role)
if ar_user = already_registered?(email) || user = self.save
Participant.make(ar_user||user, board, role)
end
user
end
I do this rspec test on it:
it "should return the user if the user is not already registered" do
lambda do
user = #new_user.can_save(#board, "Manager")
end.should change(User,:count).by(1)
end
I get this error:
undefined method `id' for true:TrueClass
Why is that?

save method returns true or false, not a saved instance of object.

Related

jwt error with method `verify_expiration'

I had a question when I try to use JWT to decode the token that is sent back from the frontend. When the token is decoded to be “2”, which is a user id for me to grab the user in the backend, I got this error: “NoMethodError: undefined method `include?’ for 2:Integer”, which is from the following codes in JWT source codes:
def verify_expiration
return unless #payload.include?('exp')
raise(JWT::ExpiredSignature, 'Signature has expired') if #payload['exp'].to_i <= (Time.now.to_i - exp_leeway)
end
What should I do to fix this?
my application controller file looks like this:
class ApplicationController < ActionController::API
def encode_token(payload)
JWT.encode(payload, 'secret')
end
def auth_header_token
request.headers['Authorization'].split(' ')[1]
end
def session_user
binding.pry
decoded_hash = decoded_token
if !decoded_hash.empty?
user_id = decoded_hash[0]["user_id"]
user = User.find_by :id=>user_id
end
end
def decoded_token
if auth_header_token
begin
JWT.decode(auth_header_token, 'secret',true, algorithm: 'HS256')
rescue JWT::DecodeError
[]
end
end
end
end
my session_controller looks like this:
class SessionController < ApplicationController
def login
user = User.find_by :email=>params[:email]
if user && user.authenticate(params[:password])
payload = user.id
token = encode_token(payload)
render json: {
user:user, include: ['order', 'favorites','orders.dishes','favorites.dishes'],
jwt:token
}
else
render json: {status: "error", message: "We don't find such an user according to your information,please try again."}
end
end
def auto_login
if session_user
render json: session_user
else
render json: {errors: "No User Logged In."}
end
end
end
Should I change the way I encode user_id?
Just found that the problem is I need to encode user_id as an object, not just the id itself, because JWT can check it as an object, and that is where the error message comes from. So, instead of
payload = user.id
token = encode_token(payload)
should have set:
payload = {user_id: user.id}
token = encode_token(payload)

Rails undefined method count

I am trying to check that an address isn't being used before I delete it. My code is as follows:
def destroy
#address = current_user.addresses.find_by_id(params[:id])
redirect_to user_addresses_path(current_user) if #address.nil?
if Organisation.find_by_address_id(params[:id]).count == 0 && Event.find_by_address_id(params[:id]).count == 0
#address.destroy
redirect_to user_addresses_path(current_user)
else
flash[:error] = "Cannot delete address because it is being used"
redirect_to user_addresses_path(current_user)
end
end
however, this gives me an error:
undefined method `count' for nil:NilClass
What am I doing wrong?
Organisation.find_by_address_id(params[:id]) will return a single object, or nil if one without that address_id does not exist.
Perhaps you meant Organisation.find_all_by_address_id(params[:id]).

record_timestamp = false not working from model

I want to track the last_login DateTime of my user, without changing the updated_at attribute.
So inside my Model attribut I put:
def login!(session)
session[:user_id] = id
User.record_timestamp = false
self.touch(:last_login_at)
User.record_timestamp = true
end
also tried, which is the same:
def login!(session)
session[:user_id] = id
self.last_login_at = Time.now
User.record_timestamps = false
self.save(:validate => false)
User.record_timestamps = true
end
But update_at column still is updated after each login.
It seems that User.record_timestamps = false doesn't have any effect when being called from the model directly. (I use to call this method from controller or rake tasks without any problem)
please don't tell me to use update_attribute :last_login_at, Time.now which in Rails 3.1 doesnt set the updated_at column: I'm using rails 3.0.9!
Any idea?
It's really more DRY for me to do this update from the model and not from any controller...
--------------------
[edit] Hummmmmm seems like a bug in rails: I have a nested Class SubUser < User.
When I replace User.record_timestamps = false by self.class.record_timestamps = false then it's working. It's quite strange because:
1) I'm calling #user.login! with a real class User (User.first.login!)
2) even if I were calling SubUser.first.login! the command User.record_timestamps should affect too SubUser class, right?
This is the way I did this before, please give a shot.
def login!(session)
session[:user_id] = id
class << self
def record_timestamps; false; end
end
self.last_login_at = Time.now
self.save(:validate => false)
class << self
remove_method :record_timestamps
end
end
Let me know if it helps you anyway.
I would try using update_attribute because it doesn't do validations so maybe it doesn't update the timestamps either. I'm not sure if it will work:
def login!(session)
update_attribute :last_login_at, Time.now
end

Testing for false with the Twitter Gem in rails 3

I'm using the Twitter gem, and I want to take a list of users from my Friend model and test to see if they're being following a Twitter user, then ... unfollow if the Twitter API returns false. Trouble is, it seems the code I'm using below never evaluates as false, even when the API returns false so it's always reverting to the else section.
I've tried variations like if ret == 'false' and it's not worked.
ret = #t.friendship?(#id_str, f.screen_name)
if ret == false
#t.unfollow(f.screen_name)
puts "#{f.screen_name} has been unfollowed."
self.update_unfollowed_column(f.id, false)
else
self.update_following_column(f.id)
end
In the console, though, if I do:
r = t.friendship?('user1', 'user2')
=> false
And then, I can do:
r == false
=> true
So, I'm not sure exactly what I'm doing wrong with the code in my Friend model.
Before the if statement, try debugging what the result is from the friendship? method:
logger.info ret.class.name # => FalseClass if it's actually false,
# => String if it's 'false'
logger.info ret.inspect # => "false" if it's false.
logger.info((ret == false).inspect) # => Should be "true"

Undefined Method `authorize_from_request' using OAuth and Twitter Gem in Ruby on Rails 3

Im getting the following error:
undefined method `authorize_from_request'
Based on the documenation here: http://oauth.rubyforge.org/rdoc/classes/OAuth/Consumer.html
That method doesnt exist, but I saw this method used here:
http://teachmetocode.com/screencasts/oauth-with-the-twitter-gem/ and
so I'm guessing it was deprecated some time ago, but I can't seem to
find its replacement and was wondering what other way could I go about
solving this issue?
Thanks in Advance!
Controller Code:
class TwitterController < ApplicationController
def index
end
def login
oauth_request_token = oauth.get_request_token(:oauth_callback => "http://gnome.local/twitter/finalize")
session[:request_token] = oauth_request_token.token
session[:request_secret] = oauth_request_token.secret
redirect_url = oauth_request_token.authorize_url
redirect_url = "http://" + redirect_url unless redirect_url.match(/^http:\/\//)
redirect_to redirect_url
end
def finalize
oauth.authorize_from_request(session[:request_token], session[:request_secret], params[:oauth_verifier])
#client = Twitter::Client.new(oauth).verify_credentials
session[:request_token] = nil
session[:request_secret] = nil
oauth_access_token = oauth.get_access_token
#oauth_token = session[:oauth_token] = oauth_access_token.token
session[:oauth_secret] = oauth_access_token.secret
end
def client
oauth.authorize_from_access(session[:auth_token])
end
def oauth
#oauth ||= OAuth::Consumer.new(APP_CONFIG[:twitter][:consumer_key], APP_CONFIG[:twitter][:consumer_secret], :site => "http://api.twitter.com", :request_endpoint => "http://api.twitter.com", :sign_in => true);
end
end
(Original Post: http://groups.google.com/group/oauth-ruby/browse_thread/thread/614b27e4f5d80fab)
Got the same problem, the solution is to use according to the (old) Twitter gem:
request_token.get_access_token(oauth_verifier: params[:oauth_verifier])