Operator does not exist: jsonb = integer - postgresql

I am getting the following postgres error:
"operator does not exist: jsonb = integer"
I have my application hosted on Heroku and am using a Postgres 9.4 DB. Below is what my accounts controller looks like with the ahoy_matey analytics gem.
Accounts Controller
class AccountsController < ApplicationController
before_filter :authenticate_user!
def index
if current_user.business_id
#business = Business.find(current_user.business_id)
# analytics
#monthly_business_views = ahoy_event_sum("Page Viewed", #business.id)
#monthly_get_websites = ahoy_event_sum("Visited Website", #business.id)
#monthly_get_directions = ahoy_event_sum("Directions Viewed", #business.id)
#monthly_get_fb_shares = ahoy_event_sum("Shared via Facebook", #business.id)
#monthly_get_tweets = ahoy_event_sum("Tweeted via Twitter", #business.id)
#reviews = Review.where(:business_id => #business).all
end
end
...
def ahoy_event_sum(event, business_id)
Ahoy::Event.where(name:event, properties: business_id).count
end
end
Ahoy Events Model
module Ahoy
class Event < ActiveRecord::Base
self.table_name = "ahoy_events"
belongs_to :visit
belongs_to :user
serialize :properties, JSON
end
end
I have intermediate skills and apologize if this question has a simple fix, please provide any details on how I would solve this issue. Thanks!

Related

PG::SyntaxError at /bookmarks - I'm unable to work out why the SQL query is wrong

When running my application using sinatra, I get the error message PG::SyntaxError at /bookmarks
ERROR: syntax error at or near "{" LINE 1: SELECT * FROM users WHERE id = {:id=>"5"} ^
It happens when I click the submit button on /users/new route which should then take me to index route /.
The backtrace provides the following information
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in async_exec
#connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in query
#connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/user.rb in find
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
app.rb in block in <class:BookmarkManager>
#user = User.find(id: session[:user_id])
This is the database_connection file
require 'pg'
class DatabaseConnection
def self.setup(dbname)
#connection = PG.connect(dbname: dbname)
end
def self.connection
#connection
end
def self.query(sql)
#connection.exec(sql)
end
end
This is the user model
require_relative './database_connection'
require 'bcrypt'
class User
def self.create(email:, password:)
encypted_password = BCrypt::Password.create(password
)
result = DatabaseConnection.query("INSERT INTO users (email, password) VALUES('#{email}', '#{encypted_password}') RETURNING id, email;")
User.new(id: result[0]['id'], email: result[0]['email'])
end
attr_reader :id, :email
def initialize(id:, email:)
#id = id
#email = email
end
def self.find(id)
return nil unless id
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
User.new(
id: result[0]['id'],
email: result[0]['email'])
end
end
This is the controller
require 'sinatra/base'
require './lib/bookmark'
require './lib/user'
require './database_connection_setup.rb'
require 'uri'
require 'sinatra/flash'
require_relative './lib/tag'
require_relative './lib/bookmark_tag'
class BookmarkManager < Sinatra::Base
enable :sessions, :method_override
register Sinatra::Flash
get '/' do
"Bookmark Manager"
end
get '/bookmarks' do
#user = User.find(id: session[:user_id])
#bookmarks = Bookmark.all
erb :'bookmarks/index'
end
post '/bookmarks' do
flash[:notice] = "You must submit a valid URL" unless Bookmark.create(url: params[:url], title: params[:title])
redirect '/bookmarks'
end
get '/bookmarks/new' do
erb :'bookmarks/new'
end
delete '/bookmarks/:id' do
Bookmark.delete(id: params[:id])
redirect '/bookmarks'
end
patch '/bookmarks/:id' do
Bookmark.update(id: params[:id], title: params[:title], url: params[:url])
redirect('/bookmarks')
end
get '/bookmarks/:id/edit' do
#bookmark = Bookmark.find(id: params[:id])
erb :'bookmarks/edit'
end
get '/bookmarks/:id/comments/new' do
#bookmark_id = params[:id]
erb :'comments/new'
end
post '/bookmarks/:id/comments' do
Comment.create(text: params[:comment], bookmark_id: params[:id])
redirect '/bookmarks'
end
get '/bookmarks/:id/tags/new' do
#bookmark_id = params[:id]
erb :'/tags/new'
end
post '/bookmarks:id/tags' do
tag = Tag.create(content: params[:tag])
BookmarkTag.create(bookmark_id: params[:id], tag_id: tag.id)
redirect '/bookmarks'
end
get '/users/new' do
erb :'users/new'
end
post '/users' do
user = User.create(email: params[:email], password: params[:password])
session[:user_id] = user.id
redirect '/bookmarks'
end
run! if app_file == $0
end
self.find(id), in the user model, is where the potentially offending SQL query resides.
I've tried;
"SELECT * FROM users WHERE id = #{id}"
and "SELECT * FROM users WHERE id = '#{id}'"
Beyond that, I'm stumped. The query looks fine, but sinatra is having none of it.
Hopefully someone can help me resolve this.
Thanks, in advance.
You're call find with a hash argument:
User.find(id: session[:user_id])
but it is expecting just the id:
class User
...
def self.find(id)
...
end
...
end
Then you end up interpolating a hash into your SQL string which results in invalid HTML.
You should be saying:
#user = User.find(session[:user_id])
to pass in just the id that User.find expects.
You're also leaving yourself open to SQL injection issues because you're using unprotected string interpolation for your queries rather than placeholders.
Your query method should use exec_params instead of exec and it should take some extra parameters for the placeholder values:
class DatabaseConnection
def self.query(sql, *values)
#connection.exec_params(sql, values)
end
end
Then things that call query should use placeholders in the SQL and pass the values separately:
result = DatabaseConnection.query(%q(
INSERT INTO users (email, password)
VALUES($1, $2) RETURNING id, email
), email, encypted_password)
result = DatabaseConnection.query('SELECT * FROM users WHERE id = $1', id)
...

Calling Document.find with nil is invalid MongoId in Rails 4

There are three models in my app: User, Subject and Note.
I've already embedded Note model into Subject model and it works. Now when I try to embed Subject into User always get Mongoid::Errors::InvalidFind coming from this line of code:
In the method one should define to use in before_action at the beginning of the controller
#user = User.find(params[:user_id])
subjects_controller
class SubjectsController < ApplicationController
#before_filter :authenticate_user!, only: [:index]
before_action :set_subject, only: [:show, :edit, :update, :destroy]
before_action :load_user
def index
#subjects = #user.subjects
end
def new
#subject = #user.subjects.build
end
def show
end
def create
#subject = #user.subjects.create(subject_params)
respond_to do |format|
if #subject.save
format.html {redirect_to subject_path(#subject)}
else
format.html {render 'new'}
end
end
end
def update
if #subject.update(subject_params)
redirect_to #subject
else
render 'edit'
end
end
def delete
end
private
def subject_params
params.require(:subject).permit(:name)
end
def set_subject
#subject = #user.subject.find(params[:id])
end
def load_user
#user = User.find(params[:user_id])
end
end
Routes
resources :users do
resources :subjects do
resources :notes
end
end
Right now I'm pretty stuck here because haven't found a way to work this around, hope someone around can give a hand.
Take into account this RoR best practice "Resources should never be nested more than 1 level deep." http://guides.rubyonrails.org/routing.html#nested-resources
A collection may need to be scoped by its parent, but a specific member can always be accessed directly by an id, and shouldn’t need scoping (unless the id is not unique, for some reason).
http://weblog.jamisbuck.org/2007/2/5/nesting-resources

ActiveResource Update Operation :: Can't mass-assign protected attributes: created_at, id, updated_at

When I try to update and save ActiveResource I am getting following error.
on console
> m = Machine.first
=> #<Machine:0xb07a0d4 #attributes={"created_at"=>"2013-04-22T09:13:56Z", "id"=>1, "name"=>"laptop", "updated_at"=>"2013-04-22T09:13:56Z"}, #prefix_options={}, #persisted=true>
> m.name = 'mouse'
=> "mouse"
> m.save
ActiveResource::ServerError: Failed. Response code = 500. Response message = Internal Server Error
on server
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: created_at, id, updated_at):
app/controllers/machines_controller.rb:62:in `block in update'
app/controllers/machines_controller.rb:61:in `update'
Here is ActiveResource model
class Machine < ActiveResource::Base
self.site = 'http://localhost:3000'
end
Here is ActiveRecord model
class Machine < ActiveRecord::Base
attr_accessible :name
end

CanCan singleton loading with pluralized class name

I'm currently experiencing an issue with the latest version of CanCan. It seems that the gem won't load singleton resources with pluralized names.
class Preferences < ActiveRecord::Base
self.table_name = 'preferences'
belongs_to :user
end
class User < ActiveRecord::Base
has_one :preferences
end
#controller
class PreferencesController < ApplicationController
before_filter :authenticate_user! #from Devise
load_and_authorize_resource :singleton => true,
:through => :current_user,
:through_association => :preferences,
:parent => false
end
#ability.rb
class Ability
include CanCan::Ability
def initialize(user)
can [:read, :update], Preferences, :user_id => user.id
end
end
I keep getting an error like this when I run my controller spec:
Failures:
1) PreferencesController GET #show should return http success
Failure/Error: get :show
NameError:
uninitialized constant Preference
# ./spec/controllers/preferences_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
It seems no matter what combination of load_resource arguments I try, I can't get my specs to pass again without reverting back to loading the resource manually like this:
class PreferencesController < ApplicationController
before_filter :authenticate_user!
def show
#preferences = current_user.preferences
authorize! :read, #preferences
end
end
Is there some magic combination of load_and_authorize_resource parameters I need to use? I have this same configuration working in another singleton controller where the resource falls under normal Rails conventions (i.e. User has_one :profile), so I know this works already under normal situations.

Redirected to http://localhost:3000/session/new

So I have a rails app 2.x app that works fine via the web, but when trying to perform a POST I keep getting "Redirected to http://localhost:3000/session/new Filter chain halted as [:require_user] rendered_or_redirected.". In my iPhone app, I can create a new session and sign-in via my iPhone app, but cannot POST to say the POSTS_Controller.
I have this in my code
Posts_Controller
before_filter :require_user, :only => [:create, :update, :destroy]
Application_Controller
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
include AuthenticatedSystem
include Geokit::Geocoders
helper :all # include all helpers, all the time
#session :session_key => '_cwa_session_id'
#filter_parameter_logging :password
# See ActionController::RequestForgeryProtection for details
# Uncomment the :secret if you're not using the cookie session store
protect_from_forgery # :secret => 'eejj7eded74769099999944a729b4f'
#filter_parameter_logging(:password)
before_filter :login_from_cookie
before_filter :find_user_interests
before_filter :find_user_posts
protected
def find_user_interests
#user_interests = cur_user ? cur_user.interesting_posts : []
logger.debug "User interests hash: #{current_user.inspect}"
end
def find_user_posts
#user_posts = cur_user ? cur_user.posts : []
end
def cur_user
User.find(session[:user_id]) if session[:user_id]
end
def require_user
unless cur_user
flash[:error] = "You must be logged in to do that."
redirect_to '/session/new'
return false
end
end
geocode_ip_address
def geokit
#location = session[:geo_location]
end
end
I have been working on this for 2 months and cannot figure out the issue. In my iPhone app I am using ObjectiveResource. I am sending over json and have "Mime::Type.register_alias "application/json", :json" set up on the rails side.
I am not a rails developer, but the before filter for require_user is unable to pass the cur_user test in that is cannot find :user_id in the session hash. Are you sure that you have a session that persists when using the iPhone? Are you using devise for authentication? Just for kicks, does it work if you manually pass the user_id as params?