redircting error in ruby on rails - forms

I'm new to ruby on rails. I tried to redirect to outlet_controller#map, but the below code redirect me to #show. what i am doing wrong. help me to sort out.
my route is
namespace :api do
get 'outlet/map' => 'outlets#map'
end
my controller is
class Api::OutletsController < ApplicationController
http_basic_authenticate_with :name => "admin", :password => "password"
skip_before_filter :authenticate_user!
before_filter :fetch_outlets, :except => [:index, :create]
def fetch_outlets
#outlet = Outlet.find_by_id(params[:id])
end
def index
respond_to do |format|
#outlets = Outlet.select(:name, :description, :latitude, :longitude, :contact, :image_url, :emailid).all
##outlets = Outlet.all
format.json { render json: #outlets}
end
end
def auto_complete
params.permit!
query = params[:query]
#outlet = Outlet.select(:name).where("name like ?","#{query}%")
if #outlet.present?
respond_to do |format|
format.json { render json: #outlet }
end
elsif
render :json=> {:status=>'error', :message=>'Data not found'}
end
end
def search
params.permit!
query = params[:query]
puts YAML::dump(query)
#outlet = Outlet.select(:name, :description, :latitude, :longitude, :contact, :image_url, :emailid).where("name like ?","%#{query}%")
if #outlet.present?
respond_to do |format|
format.json { render json: #outlet }
end
elsif
render :json=> {:status=>'error', :message=>'Data not found'}
end
end
def show
respond_to do |format|
format.json { render json: #outlet }
end
end
def create
#outlet = Outlet.new(params[:outlets])
respond_to do |format|
if #outlet
format.json { render json: #outlet, status: :created }
else
format.json { render json: #outlet.errors, status: :unprocessable_entity }
end
end
end
def update
if #outlet.update_attributes(outlet_params)
render :json=> {:status=>'success', :message=>'Successfully Updated'}
else
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
def map
super
end
def destroy
if #outlet.destroy
render :json=> {:status=>'success', :message=>'Successfully Removed'}
else
format.json { render json: #outlet.errors, status: :unprocessable_entity }
end
end
private
def outlet_params
params.require(:outlets).permit(:name, :brand_id, :latitude, :langitude, :location, :description, :image_url, :contact, :emailid)
end
end
my development log for
/api/outlets/map
is
Started GET "/api/outlets/map" for 127.0.0.1 at 2015-06-01 17:18:59 +0530
Processing by Api::OutletsController#show as JSON
Parameters: {"id"=>"map"}
[1m[35mOutlet Load (0.2ms)[0m SELECT `outlets`.* FROM `outlets` WHERE `outlets`.`id` = 0 LIMIT 1
Completed 200 OK in 15ms (Views: 0.3ms | ActiveRecord: 0.2ms)
why i'm redirect to outlets_controller#show? could anyone help to sort out this problem...

The problem could be the order of route definitions in your routes.rb.
This order of routes would trigger the problematic behaviour, because Rails will use the first route that matches the request:
YourApp.routes.draw do
namespace :api do
resources :outlets # defines the show route
get 'outlet/map' => 'outlets#map'
end
end
To fix this, change the order of your routes:
YourApp.routes.draw do
namespace :api do
get 'outlet/map' => 'outlets#map'
resources :outlets # defines the show route
end
end
Now the route outlet/map matches before outlet/:id does.
You can also try this route definition if it is applicable:
YourApp.routes.draw do
namespace :api do
resources :outlets do
get 'map', on: :collection
end
end
end

Related

Ruby on Rails Tutorial NoMethodError in Users#index

I'm reading Michael Hartl's great "The Ruby on Rails Tutorial". And I faced a problem that wasn't described in the book.
I push a submit button on a Sign up page with blank fields, then, as it expected, the mistakes messages like these appears:
Name can't be blank
Email can't be blank
Email is invalid
Password can't be blank
But the URL changes from http://[::1]:3000/signup to http://[::1]:3000/users
Then I push the Chrome's refresh button and get redirecting to exactly http://[::1]:3000/users URL.
I understand that the pushing the submit button directs to .../users URL. How to change this route to the right one (still http://[::1]:3000/signup)?
Here's my users_controller.rb file
class UsersController < ApplicationController
before_action :logged_in_user, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
#users = User.where(activated: true).paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
redirect_to root_url and return unless #user.activated?
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'users/new', status: :unprocessable_entity
end
end
def edit
#user = User.find(params[:id])
end
end
Here's my routes.rb file
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
default_url_options :host => "example.com"
resources :users
end
Thanks in advance!

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)
...

Facebook redirects to sign up page after authenticating user Rails

I am intergrating Facebook login using device, and after allowing Facebook to get your info it redirects you to the sign up page. Here's my code:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :description, :photo ])
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :first_name, :last_name, :description, :photo ])
end
end
Callback controller
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, :event => :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
And my user model is
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.name # assuming the user model has a name
user.image = auth.info.image # assuming the user model has an image
end
end
I'd really appreciate an extra eye on what I'm doing wrong, or where I am missing something. Thanks!
You need to add this column for provider and uid to your users table, i think rails can't match your user :
rails g migration add_provider_and_uid_to_users provider:string uid: string
And try to write me the rails server response it Can help to figure out the bug source

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

Carrierwave + Fog (S3) + Heroku: TypeError (can't convert Hash into String)

I have an application on Heroku that uses Carrierwave to upload images to S3. The app is running perfectly on local machine but on Heroku throws the following error and fails the uploading to S3:
TypeError (can't convert Hash into String):
2011-09-23T15:12:07+00:00 app[web.1]: app/controllers/admin/albums_controller.rb:49:in `create'
2011-09-23T15:12:07+00:00 app[web.1]: app/controllers/admin/albums_controller.rb:48:in `create'
That line corresponds to the "if #album.save" instruction.
My Albums controller create action is:
def create
#album = Album.new(params[:album])
respond_to do |format|
if #album.save
format.html { redirect_to(admin_album_path(#album), :notice => 'Àlbum creat correctament.') }
format.xml { render :xml => [:admin, #album], :status => :created, :location => #album }
else
format.html { render :action => "new" }
format.xml { render :xml => #album.errors, :status => :unprocessable_entity }
end
end
end
My Carrierwave initializer:
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => APP_CONFIG['storage']['s3_access'],
:aws_secret_access_key => APP_CONFIG['storage']['s3_secret'],
}
config.fog_directory = 'romeu'
config.fog_host = 'http://xxxxx.s3.amazonaws.com'
config.fog_public = true
config.root = Rails.root.join('tmp')
config.cache_dir = 'carrierwave'
end
My image_uploader.rb:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Album Cover version
version :cover do
process :square_resize => [150,150]
end
# Thumb version
version :thumb do
process :square_crop => [80,80]
end
def square_crop(width, height)
manipulate! do |img|
side = [img['width'], img['height']].min
x = (img['width'] - side) / 2
y = (img['height'] - side) / 2
img.crop("#{side}x#{side}+#{x}+#{y}")
img.resize("#{width}x#{height}")
img
end
end
def square_resize(width, height)
manipulate! do |img|
img.resize("#{width}x#{height}")
img
end
end
# Valid list
def extension_white_list
%w(jpg jpeg gif png)
end
end
My config.ru:
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
use Rack::Static, :urls => ['/carrierwave'], :root => 'tmp'
run Encen::Application
I have inspected the #album object and everything seems okay:
_mounters:
:image: !ruby/object:CarrierWave::Mount::Mounter
_memoized_option:
?
- :mount_on
:
column: :image
integrity_error:
options: {}
processing_error:
record: *id001
uploader: !ruby/object:ImageUploader
cache_id: 20110923-0810-1-0644
file: !ruby/object:CarrierWave::SanitizedFile
content_type: image/jpeg
file: /app/tmp/carrierwave/20110923-0810-1-0644/image.jpg
original_filename:
filename: image.jpg
model: *id001
mounted_as: :image
original_filename: image.jpg
versions:
:thumb: !ruby/object:
file: !ruby/object:CarrierWave::SanitizedFile
cache_id: 20110923-0810-1-0644
content_type: image/jpeg
file: /app/tmp/carrierwave/20110923-0810-1-0644/image.jpg
original_filename:
filename: image.jpg
model: *id001
mounted_as: :image
original_filename: image.jpg
parent_cache_id: 20110923-0810-1-0644
versions: {}
:cover: !ruby/object:
cache_id: 20110923-0810-1-0644
file: !ruby/object:CarrierWave::SanitizedFile
content_type: image/jpeg
file: /app/tmp/carrierwave/20110923-0810-1-0644/image.jpg
original_filename:
filename: image.jpg
model: *id001
mounted_as: :image
attributes:
title:
body:
model: *id001
previously_changed: {}
readonly: false
I have spent a bunch of days intending to resolve that error but unsuccessful, what I am missing?
Thanks in advance.
After long days of frustation I have solved the problem. It was such as an stupid thing like the environment vars of S3 access keys on Heroku were incorrectly defined. I don't understand why Fog gem don't gives you more accurate debugging information about that kind of errors.