How do I get a user's location using Koala in rails? - ruby-on-rails

I have the following code in my sessions controller which saves information such as Facebook friends, likes, and a user profile to my DB. The profile includes the user's location and gender but it gets saved into the DB as a string so I can't extract it.
#graph = Koala::Facebook::GraphAPI.new(current_user.token)
current_user.profile = #graph.get_object("me")
current_user.likes = #graph.get_connections("me", "likes")
current_user.friends = #graph.get_connections("me", "friends")
current_user.save
Going into the console, I can get the profile of the last user via:
u = User.last.profile
But this doesn't let me call for the location specifically, like:
User.last.profile.location
User table looks like
create_table "users", :force => true do |t|
t.string "provider"
t.string "uid"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "token"
t.string "likes"
t.string "profile"
t.string "location"
t.string "interests"
t.string "birthday"
t.string "activities"
t.string "friends"
end

like this?
graph = Koala::Facebook::API.new(#oauth_token)
#user = graph.get_object("me")
location = #user["location"]["name"]

I am using koala v2.2 and my application Facebook API Version is v2.4.
I did not get location information using just get_object("me") request. I had to pass location as fields parameter like
get_object("me?fields=first_name,last_name,location")
May be this information will be helpful for someone.
N.B: Of course you have to enable user_location scope.

The way I've used to work this out is using scopes and call these scopes in the view, which might not be the best way but is a quick fix.
The User model can be scoped by:
scope :CityName, where("profile like '%location: CityName%'")

to use Facebook Checkins since yesterday e.g.:
unless graph.get_connections('me', 'checkins', :since => 'yesterday').blank?
checkin = graph.get_connections('me', "checkins", :since => 'yesterday')
lat = checkin[0]['place']['location']['latitude']
long = checkin[0]['place']['location']['longitude']

Related

My show function in my controller is not finding the creator of an Object

I have part of a rails application where a user will create a recipe that will be saved in their "cookbook". Other users will be able to take recipes from other users. So there will be an aspect in the application that shows who created the recipe.
Schema for a Recipe
create_table "recipes", force: :cascade do |t|
t.string "recipe_name"
t.string "description"
t.integer "calories"
t.integer "carbs"
t.integer "fats"
t.integer "protein"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Where I am having trouble is displaying the recipe's creator.
def show
#user = current_user
#recipe = Recipe.find_by(params[:id])
creator = User.find_by(params[#recipe.user_id])
#creator = creator.first_name
end
So for right now I have two user's John (Id: 1) and Alex (Id:2). When I have Alex make a recipe and I put a pry under #recipe I get a user_id of 2 when I call #recipe.user_id.
However, when I put the pry under creator and call creator I get the user_id of 1 and I get John. I believe something is wrong with how I am trying to find the user using the user_id in #recipe. I was wondering if anyone know what I am doing wrong or if I need to add more information. Thanks.
This:
User.find_by(params[#recipe.user_id])
Doesn't make sense for a couple of reasons:
find_by expects a hash-like structure. Something like: User.find_by(id: xxx)
params[#recipe.user_id] doesn't make sense because that's going to be something like: params[1] which is not what you want.
This:
#recipe = Recipe.find_by(params[:id])
Also suffers from the malformed find_by.
So, try something like:
def show
#user = current_user
#recipe = Recipe.find(params[:id])
creator = #recipe.user
#creator = creator.first_name
end
This, naturally, assumes you have your association between Receipt and User set up correctly (i.e., using belongs_to).

Rendering Amazon Products

I'm using Rails to build a simple web app.
I have a form asking users to select a vice category (e.g.: smoking, shopping, drinking coffee, etc.) and how much they spend (value) per day, in euros (unit).
Schema:
create_table "vices", force: :cascade do |t|
t.string "category"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "value"
t.string "unit"
t.string "user"
t.string "hobbies"
end
After submitting the form I dynamically show a message:
<%= "Stop #{#vice.category} and you will save #{#vice.value * 365} #{#vice.unit} per year!" %>
Second line:
<%= "Here's what you can buy instead:" %>
After this, I want to show Amazon products that they can buy according to their hobbies.
For example: if you stop smoking you will save 2000 euros a year. Here are drones you can buy instead. And then I show drones from Amazon.
I have been trying to connect to Amazon Product Advertising API using amazon-ecs gem but no luck showing it so far.
I then have a show.json.builder file with this:
json.partial! "vices/vice", vice: #vice
Amazon::Ecs.configure do |options|
options[:AWS_access_key_id] = '[my access key]'
options[:AWS_secret_key] = '[my secret key]'
options[:associate_tag] = '[my associate tag]'
end
res = Amazon::Ecs.item_search('#{#vice.hobbies}', {:response_group => 'Medium', :sort => 'salesrank'})
Is this correct?
How can I show the Amazon results in show.hmtl.erb
This is my first question here on Stack OVerflow. Let me know what else I need to post to expand on the explanation.
Thanks!

Facebook OAuth with sorcery not saving emails to database

Having trouble saving new users to my database through facebook oauth, because I have email set to null: false, and it's not grabbing emails when it tries to authenticate. Do not want to change my database as a workaround.
config.facebook.key = ENV['facebook_app_id']
config.facebook.secret = ENV['facebook_api_secret']
config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
config.facebook.user_info_mapping = { :email => "email", :name=> "name"}
config.facebook.user_info_path = "me?fields=email, name"
config.facebook.scope = "email" #etc
config.facebook.display = "popup"
config.facebook.access_permissions = ["email", "user_friends", "public_profile"]
config.facebook.api_version = "v2.5"
users table looks like:
create_table "users", force: :cascade do |t|
t.string "name"
t.text "about_me"
t.string "email", null: false
t.string "crypted_password"
t.string "salt"
t.datetime "created_at"
t.datetime "updated_at"
# .....
server logs:
SQL (1.6ms) INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2016-03-14 00:50:35.548272"], ["updated_at", "2016-03-14 00:50:35.548272"]]
(0.2ms) ROLLBACK
Figured it out. The email column being null => false was screwing it up. Also, I had done this using the sorcery wiki on external authorization after setting up the basic sorcery auth, and the wiki seems to be deprecated. My user model and authentication model both had attr_accessor for email, name, etc...which was also screwing it up. Taking that out and putting authentications with a hash of accessibles in my user controller strong params worked better.
Thanks to everyone who took a look at it!
Based on your server log, your work (on controller/ model) not saving email attribute into User model.
As you declared in migration, users have to validate email (not allow null) so that User cannot be created.
Check around your controller/ model while saving user from Facebook OAuth.
Anyway, in rails, I recommend you using gem devise for user and omniauth-facebook for Facebook OAuth.

Search functionality in rails

I have jobplacement model and i want to implement search functionality which should be a keyword search i.e i mean even if you type any keyword in search and if that is present in the db of jobplacement table it should show the results.
Currently i am using following code which just matches 1 field i.e name of the company and category as in the params[:category].Following is tha code of my jobplacementcontroller/index action
if params[:search]
#search_condition = "%" + params[:search] + "%"
#searchresult = Jobplacement.where(['name LIKE ? and category = ?', #search_condition ,params[:category]])
else
#searchresult = ""
end
Also in above code although i have given condition for category its not executing properly.When i do search it gives results that matches name field but its not evaluating params[:category] condition.it shows all the records even if they are not in the params[:category].
Following are the fields in my jobplacement model :
t.string "name"
t.string "designation"
t.string "qualification"
t.integer "years_of_exp"
t.string "location"
t.integer "noofpost"
t.string "jobprofile"
t.string "salaryoffered"
t.string "contactperson"
t.string "employmenttype"
t.text "address"
t.string "city"
t.string "state"
t.string "country"
t.integer "contactno"
t.string "website"
t.text "aboutcompany"
so when i enter any keyword in search if that matches with data of any field it should return that data.How can i do this...
How can i solve this params[:category] error and how can i do keyword search that matches any record present in the database of jobplacement model not just 1 field.
check out Thinking Sphinx, it has solutions to your problems and has more features like sub string search, wild char support and more
using the squeel gem http://erniemiller.org/projects/squeel/
you can simply do:
terms = params[:search].split
Jobplacement.where {name.eq(params[:category]) & (name.like_any(terms) | designation.like_any(terms) | qualification.like_any(terms) <...>) }

Rails GeoCoder, looping through existing database and geocode_by :address, :city, :state

I have imported a .csv file of 10,000 locations and I need to loop through the database and geocode_by a few fields rather than the usual "geocode_by :address"
I am using the geocoder gem.
My database scheme looks like this
create_table "locations", :force => true do |t|
t.string "Address"
t.string "City"
t.string "State"
t.string "Zip"
t.float "latitude"
t.float "longitude"
t.datetime "created_at"
t.datetime "updated_at"
end
Can I do this in a controller action rather than on validation?
Should I do something like this:
def index
#locations = Location.all
#locations.each do |l|
new_address = "#{l.Address} #{l.City} #{l.State}"
geocode_by = :new_address
end
end
But yea, any help is greatly appreciated, thank you!
I was able to get things working with this controller code:
def index
if params[:search].present?
#locations = Location.near(params[:search], 20, :order => :distance)
else
#locations = Location.all
#locations.each do |l|
if l.latitude.nil?
new_location = "#{l.HP_Address_1} #{l.HP_City} #{l.HP_State}"
s = Geocoder.search(new_location)
l.latitude = s[0].latitude
l.longitude = s[0].longitude
l.save
end
end
end
end
It loops through every entry in the database, and if the latitude and longitude values have not been encoded it calls the correct geocoder function, and stores the returned lat / long values in the database.
I have 9k entries in my database, so I can only encode 2k per day due to the limit on the google maps api. But for folks used to encoding entries during creating using geocoded_by in their models, this will work in controllers.
This is the kind of thing I'd do with workers (delayed job or resque), since it might take some time to complete. But I'm not sure I understood the question, so this might not be the kind of answer you're expecting.
There is a rake task for this if you want to do every record in a class.
rake geocode:all CLASS=YourModel sleep=0.25

Resources