ruby like query error - mysql

This is my code for mysql like query:
def search
params.permit!
#query = params[:query]
respond_to do |format|
#outlet = Outlet.select(:name).where("name like ?","%#{#query}%")
format.json { render json: #outlet }
end
end
It renders all of my data from table. It does not respond to the query. Do you have any ideas?
My route is:
namespace :api do
resources :outlets, :defaults => { :format => 'json'}
get 'outlets/auto_complete' => 'outlets#auto_complete', :defaults => { :format => 'json'}
post 'outlets/search' => 'outlets#search', :defaults => { :format => 'json' }
end
The development.log is
Started POST "/api/outlets/search" for 127.0.0.1 at 2015-05-30 16:56:22 +0530
Processing by Api::OutletsController#search as JSON
Parameters: {"outlet"=>{"query"=>"life"}}
[1m[35mOutlet Load (0.1ms)[0m SELECT `outlets`.`name` FROM `outlets` WHERE (name like '%%')
Completed 200 OK in 28ms (Views: 22.3ms | ActiveRecord: 1.7ms)

Looking at the log file and below trace :-
Parameters: {"outlet"=>{"query"=>"life"}}
I found the issue. You need to do #query = params[:outlet][:query].

It is because params[:query] is nil, so the resulting sql is
where name like '%%'
You do have a query parameter in params[:outlet][:query] which you could use without changing your view.
However, as you're not creating or updating an Outlet, and query probably isn't an attribute of the Outlet model, it doesn't really make sense to structure the form in this way.
Try using form_tag instead of form_for and don't pass it an instance of Outlet. Also use text_field_tag instead of form.text_field. This way params[:query] will be set, instead of being wrapped under params[:outlet].
The new form would look a bit like this:
<%= form_tag do %>
<%= text_field_tag :query %>
<%= submit_tag %>
<% end %>

Related

Include parent attributes when searching via query

I have a User Model that has_many Job Applications.
Everything works great, but when I try to search Job Applications by the User's first_name I get the error below.
Error
SQLite3::SQLException: no such column: first_name: SELECT "job_applications"
From my understanding, I need to include the User attributes in the Job Application query.
How can I accomplish this?
View (job application)
<%= form_for :search, :html => {:method => :get, :id => 'search'} do |f| %>
<%= text_field_tag :terms, params[:terms], :type => 'search' %>
<% end %>
Controller (job application)
def index
#job = Job.find(params[:job_id])
#job_applications = #job.job_applications.search(params[:terms])
end
Model (job application)
def self.search(terms)
terms ||= ""
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
### I am having an issue here...
### how do i include the user attributes in this query
"first_name like '%#{term}%'"
end
where(conditions.join " OR ")
end
You have to join job_applications table with users table.
# job_applications.rb
def self.search(terms)
terms ||= ""
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
"users.first_name like :term"
end
joins(:user).where(conditions.join " OR ")
end
Avoid passing raw user's inputs into your queries directly to avoid sql injection. Use rails' built-in filters or sanitize it yourself.
def self.search(terms)
terms ||= ""
term_args = []
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
term_args << "%#{term}%"
"users.first_name like ?"
end
joins(:user).where(conditions.join(' OR '), term_args)
end

undefined method `user_revisers_path' "NoMethodError in Revisers#new "

I got this weird error I'm assuming this comes from the routes.rb part of my app. Im trying to give the chance for a user to become a reviser when they enter a form. a user can only become a reviser once so its a has_one reviser on user.rb model Thanks!
routes.rb:
Rails.application.routes.draw do
root 'pages#home'
devise_for :users ,
:path => '' ,
:path_names => { :sign_in => 'login', :sign_out => 'logout', :edit => 'profile' },
:controllers => { :omniauth_callbacks => 'omniauth_callbacks',
:registrations => 'registrations'
}
resources :users, only: [:index, :show] do
resource :reviser
end
revisers_controller:
class RevisersController < ApplicationController
before_action :set_reviser, only: [:show, :edit, :update]
before_action :authenticate_user!, except: [:show]
def index
#reviser = current_user.reviser
end
def show
end
def new
#reviser = current_user.build_reviser(params[:reviser])
#user = User.find(params[:user_id])
end
def create
#reviser = current_user.reviser.build(reviser_params)
if #reviser.save
redirect_to #reviser,notice: "saved...."
else
render :new
end
end
def edit
set_reviser
end
def update
set_reviser
if #reviser.update(reviser_params)
redirect_to #reviser, notice: "updated.."
else
render :edit
end
end
private
def set_reviser
#reviser = Reviser.find(params[:id])
end
def reviser_params
params.require(:reviser).permit(:description, :average_start, :average_end, :max_pages, :price_per, :active)
end
end
new.html
<%= form_for [current_user, #reviser] do |f| %>
<div class="row">
<div class="div.col-md-4 select">
<div class="form-group">
<label>dsd</label>
<%= f.input :description, label: false, class: 'controls',:input_html => { :id => 'description' } %>
</div>
</div>
</div>
<%= f.submit "Become Adviser", class: "btn btn-large btn-primary" %>
<% end %>
Error log:
Rendered revisers/_form.html.erb (14.7ms)
Rendered revisers/new.html.erb within layouts/application (15.9ms)
Completed 500 Internal Server Error in 48ms (ActiveRecord: 1.1ms)
ActionView::Template::Error (undefined method `user_revisers_path' for #<#<Class:0x007faf35f0cc60>:0x007faf35ee7e60>):
5: <div class="panel-body">
6: <div class="container">
7:
8: <%= form_for [current_user, #reviser] do |f| %>
9:
10: <div class="row">
11: <div class="div.col-md-4 select">
app/views/revisers/_form.html.erb:8:in `_app_views_revisers__form_html_erb___2471522092853631188_70195335070980'
app/views/revisers/new.html.erb:1:in `_app_views_revisers_new_html_erb___1451348464463745171_70195280947160'
Rake routes:
Prefix Verb URI Pattern Controller#Action
root GET / pages#home
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session DELETE /logout(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/facebook/}
user_omniauth_callback GET|POST /auth/:action/callback(.:format) omniauth_callbacks#(?-mix:facebook)
user_password POST /password(.:format) devise/passwords#create
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
PATCH /password(.:format) devise/passwords#update
PUT /password(.:format) devise/passwords#update
cancel_user_registration GET /cancel(.:format) registrations#cancel
user_registration POST / registrations#create
new_user_registration GET /sign_up(.:format) registrations#new
edit_user_registration GET /profile(.:format) registrations#edit
PATCH / registrations#update
PUT / registrations#update
DELETE / registrations#destroy
user_confirmation POST /confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /confirmation/new(.:format) devise/confirmations#new
GET /confirmation(.:format) devise/confirmations#show
user_reviser POST /users/:user_id/reviser(.:format) revisers#create
new_user_reviser GET /users/:user_id/reviser/new(.:format) revisers#new
edit_user_reviser GET /users/:user_id/reviser/edit(.:format) revisers#edit
GET /users/:user_id/reviser(.:format) revisers#show
PATCH /users/:user_id/reviser(.:format) revisers#update
PUT /users/:user_id/reviser(.:format) revisers#update
DELETE /users/:user_id/reviser(.:format) revisers#destroy
users GET /users(.:format) users#index
user GET /users/:id(.:format) users#show
photos GET /photos(.:format) photos#index
POST /photos(.:format) photos#create
new_photo GET /photos/new(.:format) photos#new
edit_photo GET /photos/:id/edit(.:format) photos#edit
photo GET /photos/:id(.:format) photos#show
PATCH /photos/:id(.:format) photos#update
PUT /photos/:id(.:format) photos#update
DELETE /photos/:id(.:format) photos#destroy
pages GET /pages(.:format) pages#index
POST /pages(.:format) pages#create
new_page GET /pages/new(.:format) pages#new
edit_page GET /pages/:id/edit(.:format) pages#edit
page GET /pages/:id(.:format) pages#show
PATCH /pages/:id(.:format) pages#update
PUT /pages/:id(.:format) pages#update
DELETE /pages/:id(.:format) pages#destroy
autocomplete_user_country_suggestions GET /suggestions/autocomplete_user_country(.:format) suggestions#autocomplete_user_country
autocomplete_user_city_suggestions GET /suggestions/autocomplete_user_city(.:format) suggestions#autocomplete_user_city
autocomplete_user_school_suggestions GET /suggestions/autocomplete_user_school(.:format) suggestions#autocomplete_user_school
autocomplete_user_major_suggestions GET /suggestions/autocomplete_user_major(.:format) suggestions#autocomplete_user_major
suggestions GET /suggestions(.:format) suggestions#index
POST /suggestions(.:format) suggestions#create
new_suggestion GET /suggestions/new(.:format) suggestions#new
edit_suggestion GET /suggestions/:id/edit(.:format) suggestions#edit
suggestion GET /suggestions/:id(.:format) suggestions#show
PATCH /suggestions/:id(.:format) suggestions#update
PUT /suggestions/:id(.:format) suggestions#update
DELETE /suggestions/:id(.:format) suggestions#destroy
conversation_messages GET /conversations/:conversation_id/messages(.:format) messages#index
POST /conversations/:conversation_id/messages(.:format) messages#create
conversations GET /conversations(.:format) conversations#index
POST /conversations(.:format) conversations#create
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
PATCH /posts/:post_id/comments/:id(.:format) comments#update
PUT /posts/:post_id/comments/:id(.:format) comments#update
DELETE /posts/:post_id/comments/:id(.:format) comments#destroy
post_places GET /posts/:post_id/places(.:format) places#index
POST /posts/:post_id/places(.:format) places#create
new_post_place GET /posts/:post_id/places/new(.:format) places#new
edit_post_place GET /posts/:post_id/places/:id/edit(.:format) places#edit
post_place GET /posts/:post_id/places/:id(.:format) places#show
PATCH /posts/:post_id/places/:id(.:format) places#update
PUT /posts/:post_id/places/:id(.:format) places#update
DELETE /posts/:post_id/places/:id(.:format) places#destroy
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
You have a singular resource definition for your :reviser route. This makes sense for what you're trying to do, however the route generated by form_for [current_user, #reviser] will try to generate a route with both a :user_id, and an :id to identify your reviser.
So, the :id field isn't defined in your case since resource :reviser doesn't create an :id.
The solution is to explicitly set the url in your form_for to the route your want:
It should be something along the lines of:
form_for #reviser, url: edit_user_reviser_path(user_id: current_user.id)
The bigger issue with your code is that you're still directly referencing reviser by id in your controller. Under your current route settings, this will return an error on the Reviser.find() method. However, more importantly this presents a security concern since a malicious user could send an id param in the PATCH request to hijack and update a record that belongs to another user.
A simple solution is to just reference the reviser object directly on current_user.
def set_reviser
#reviser = current_user.reviser
end

Rspec - GET show with respond_to on specific json view

I'm trying to use Rspec-rails on my application but I fail when I try to verify the response of my request.
This is my code :
# app/controllers/user_controller.rb
# GET api/users/:id
def show
#user = User.find(:id)
respond_to do |format|
format.json {render template: "/api/users/detailed"}
end
end
...
# spec/controllers/api/users_controller_spec.rb
require "spec_helper"
describe Api::UsersController do
include Devise::TestHelpers
describe "GET #show" do
user = FactoryGirl.build(:user)
it "assigns the requested user to #user" do
get :show, :format => 'json', :id => user.id
assigns(:user).should eq(#user)
end
it "renders the #detailed view" do
get :show, :format => 'json', :id => user.id
response.should be_respond_to("api/users/detailed")
#expect(response).to render_template("api/users/detailed")
#expect(subject).to render_template("/api/users/detailed")
#render(:template => "/api/users/detailed.json.rabl", :format => "json")
#response.should render_template("/api/users/detailed.json.rabl")
end
end
I commented a part of what I have tested.
I just want to be sure that my controller respond_to a template called "api/users/detailed".
Most often, I have the following error :
expecting <"api/users/detailed"> but rendering with <"">
I'm pretty sure my request called the controller because the first describe "assigns the requested user to #user" works.

Validations for Importing CSV data into MySql database in Rails 3.1?

i implemented the task of importing data from csv into MySQL database successfully. Now, my requirement is: i need to get error message with line number, if there is any mis match of data in csv file while importing.
This is my controller code:
**require 'csv' #at the top and followed by...
def load_csv
# no code
end
def import_csv
parsed_file = CSV.foreach(params[:csv].tempfile,:headers => true) do |row|
row = row.to_hash.with_indifferent_access
Institute.create!(row.to_hash.symbolize_keys)
redirect_to :action => :index
end
In my view/ load_csv.html.erb:
<%= form_for(:institute, :url => import_csv_institutes_path, :html => {:multipart => true}) do |f| %>
<div class="field">
<%= file_field_tag :csv %>
<%= f.submit 'Import' %>
</div>
<% end %>
These are the only two steps i used for importing. Model validations are working only for form and for csv, an error page displayed..
Please try to help me out.........................
Assign an error message to the flash[:notice] variable in the import_csv method. Do it before redirect.
http://guides.rubyonrails.org/action_controller_overview.html

rails 3 json custom json formatting

I have a collection of #clients with attributes id and email
I want to render this json format
[
{"id":" 1","label":"johndoe#yahoo.com","value":"1"},{"id":" 2","label":"paulsmith#gmail.com.com","value":"2"}
]
in clients_controller I defined the following method
def search
#clients = Client.where(:user_id => current_user.id).select('id','email')
render :partial => "clients/search"
end
and here is the view _search.json.erb
[
<%= raw #client.map{|client| '{"id":"' +" #{client.id}" +'","label":"' + "#{client.email}" + '","value":"' +"#{client.id}" +'"}' }.join(",") %>
]
this is working, but I found it fugly...is there a more elegant way to generate a custom json format in a view?
Use a helper function you call from the view to format the output or a library function you call from the controller. Example (of later):
def search
#clients = Client.where(:user_id => current_user.id).select('id','email')
respond_to do |format|
format.html
format.json do
render :json => custom_json_for(#clients)
end
end
end
private
def custom_json_for(value)
list = value.map do |client|
{ :id => " #{client.id}",
:label => client.email.to_s,
:value => client.id.to_s
}
end
list.to_json
end
You just need use the to_json method. In you case it's
#client.to_json(:only => [:id, :label, :value])
You could use jBuilder gem from GitHub
for clients_controller
def search
#clients = Client.where(:user_id => current_user.id)
end
and search.json.jbuilder
json.id #clients.id
json.label #clients.email
json.value #clients.id
For more info you can visit Jbuilder on RailsCast
You can use https://github.com/dewski/json_builder/ to customize your json response in the view and separate it from the controller. It's good when you need to add some "current user" depending attributes like
[{:attending => event.attending?(current_user)}]