ActiveRecord StatementInvalid (Ruby on Rails) - ruby-on-rails

So I keep getting the following error when trying to search:
ActiveRecord::StatementInvalid in Clients#search
SQLite3::SQLException: no such column: client: SELECT COUNT(*) FROM "clients" WHERE (client = '')
client.rb (model)
def self.simple_search(search_string)
self.where("client = ?", search_string)
end
index.html.erb
<div id="client-search">
<%= render(:partial=>'/search',:locals=>
{ :my_path => "/clients/search" })%>
</div>
clients_controller
def search
#clients = Client.simple_search(params[:search_string])
render :action => "index"
end
_search.html.erb
<%= form_tag my_path do %>
<h6>Search Customer</h6>
<%= text_field_tag :search_string %>
<%= submit_tag 'Search' %>
<% end %>
Any chance someone could help me with how I can get around this error please?

Is there actually a column named client in the clients table?
By the way, if there is then you could use:
def self.simple_search(search_string)
self.where(client:, search_string)
end

You don't have a column named client on your clients table. Maybe you need to be searching name or some other attribute?
def self.simple_search(search_string)
self.where("{put the column name you want to be searching here} = ?", search_string)
end
But in most cases you will need to do something like:
self.where("{put the column name you want to be searching here} LIKE '%?%'", search_string)
And to take it further, just make it a scope on your model instead of method.

Related

how to add uniq in a query

in view I have this
<div>
<% #readers.each do |reader| %>
<% user_profile_url = user_url(reader.user.username) %>
<div>
<%= link_to user_profile_url do %>
<%= reader.user.username %>
<% end %>
<span>[<%= reader.created_at.to_date %>]</span>
</div>
<% end %>
</div>
in the books_controller i have this
def readers_list
#book = Book.find(params[:id])
#readers = #book.downloads.order(created_at: :desc)
end
I have this problem: If an user download twince a book, in this list I see the username twince.
So, I know, I have to add uniq
I tried to add it at the end of the #readers, but it didn't work. How (and where) to add it?!
I also tried to make this #readers = #book.downloads.where(user_id: params[:user_id]).order(created_at: :desc), but it didn't work.
Use DISTINCT instead uniq. As you'll get everything and then do uniq, that's often considered as inefficient:
book
.downloads
.select('distinct on (downloads.user_id) downloads.*')
.order('downloads.user_id, downloads.created_at DESC')
downloads was scoped to a JOIN clause, so the created_at column was present in both tables, hence the explicit reference in both select and order.
Another alternative is to use "Group By", In rails it can be done like this
#book.downloads.order(created_at: :desc).group(:user_id)
If you want to check What's faster, 'DISTINCT' or 'GROUP BY' then here is a good place to get started.

join query works in console but not in view

I asked a previous question about how to properly structure my search query, but I find that it only works in console. What I have here is virtually identical to a search method used on another model (the other doesn't use joins), but for some reason this one returns nothing. This one also spits %5B%5D out into the url, whereas the other does not.
The search function in my model:
Class Collection
def self.search(search)
if search
joins(blob: :item).where("items.a ILIKE ?", "%#{search}%")
else
order('id DESC')
end
end
end
My controller:
#collections = if params[:search]
current_user.collections.search(params[:search]).order("created_at DESC")
else
current_user.collections.order("created_at DESC")
end
And my view:
<%= form_tag collections_path, method: 'get' do %>
<%= text_field :search, params[:search] %>
<% end %>
<% #collections.each do |c| %>
<%= c.item.a %>
blah blah
<% end %>
The terminal output I get is
`SELECT COUNT(*) FROM "collections" INNER
JOIN "blobs" ON "blobs"."id" = "collections"."blob_id" INNER JOIN
"items" ON "items"."id" = "blobs"."item_id" WHERE
"collections"."user_id" = $1 AND (items.a ILIKE '%#{search}%')
[["user_id", 1]].
Really seems like this should be working, but it's not?
Here is in the OP seeing some wrong, so the follow to the below.
In the join query, no any issue, the issue is where view & controller
You don't need the if search condition because you have already this into controller method
def self.search(search)
joins(blob: :item).where("items.a ILIKE ?", "%#{search}%")
end
Look the ILIKE key only work for PostgreSQL, if your development database is sqlite3 then the query will look like this otherwise as is
joins(blob: :item).where("lower(items.a) LIKE (?)", "%#{search.downcase}%")
change this into self.search method.
And into the controller follow this code
if params[:search].present?
#collections = current_user.collections.search(params[:search]).order("created_at DESC")
else
#collections = current_user.collections.order("created_at DESC")
end
And text field change like this
<%= text_field_tag :search, value: params[:search] %>
So the form will look like this
<%= form_tag collections_path, method: 'get' do %>
<%= text_field_tag :search, params[:search] %>
<% end %>
Hope it will work.

Rails: Display database query on HTML page, ActiveRecord

I am trying to create a search form for my rails app, the user enters a query and based off that query, I want them to see a list of links associated with that query (these links come from my 'links' table). I created the HTML form and it has the user enter a query. I use this query
<%= form_tag links_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "search", :name => nil %>
</p>
<% end %>
In my controller for the links table, I have an if statement that checks what the user has entered and it assigns Link.where('title LIKE ?', '%{#params[:search]}%') to #links. and then converts it to an array (.to_a)
Here is the statement in the index action:
def index
#links = Link.all
if params[:search]
##links = Link.find(:all, :conditions => ['title LIKE ?', '%{#params[:search]}%'])
#links = Link.where('title LIKE ?', '%{#params[:search]}%')
#links.to_a
end
end
In my index.html.erb I would like to display the result. I used <%= #links %> however, it displays the ActiveRecord: #<Link::ActiveRecord_Relation:0x0000000d5c69f0>
How could I convert the query result ActiveRecord into an array, so then I could be able to index it?
Thanks.
Don't EVER EVER EVER EVER use
#links = Link.where('title LIKE ?', '%{#params[:search]}%')
this is a security issue. Check http://railscasts.com/episodes/25-sql-injection.
In order to see all likes as an output just simply do
#links = Link.where('title LIKE ?', params[:search]')
and in Views do
<%= #links.to_a %>
That should help :)
You need to assigns #links like this:
#links = #links.to_a
By the way, if you want render link one-by-one using something like #links.each, you do not need to convert #links to array.

rails 4 populate dropdown values from database

I have a dropdown in a rails form:
<%= f.select :lists, [["test1", 1], ["test2", 0]] %>
This works fine but how can I make it dynamic. (interacting with model data)
I have a controller with an action containing #list = List.all
How can I populate id and name in my combobox. I've been searching around, but I am unclear about it. Can anyone help>
You can use options_from_collection_for_select.
<% options = options_from_collection_for_select(#list, 'id', 'name') %>
<%= f.select :all_val, options %>
Don't quite have enough reputation to respond to your question in the thread above #learner but there's a good chance that #overflow didn't have #list defined in his controller.
To solve my case I put my equivalent of #list (in this case #restaurants) in my "def new" method since I was using it to help create new items with associated restaurants.
# GET /specials/new
def new
#special = Special.new
#restaurants = Restaurant.all // Look Here
end
Additionally, :all_val in the original response should be the parameter you want to pass in to the database. In my case it was :restaurant_id
This worked for me
# view
<%= form.select(:list_id) do %>
<% #list.each do |l| -%>
<%= content_tag(:option, l.name, value: l.id) %>
<% end %>
<% end %>
and
# controller
#list ||= List.all
`

Rails' Ransack Search with check_box for an associated model

I got lost when I use 'ransack', a Rails Serching gem.
What I want to do is to work check-boxes for an asociated model.
Here is my code.
shows_controller.rb
class ShowsController < ApplicationController
def index
#q = Show.search(params[:q])
#shows = #q.result(:distinct => true)
#shows = #shows.joins(:tickets)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #shows }
end
end
index.html.erb
<%= search_form_for #q do |f| %>
<%= f.label "Show's Title: " %>
<%= f.search_field :title_cont %>
<%= f.label "Buy at:" %>
<%= check_box_tag 'q[shows_tickets_store_cont[]]', 'venue' %>At Venue
<%= check_box_tag 'q[shows_tickets_store_cont[]]', 'ticketmaster' %>Ticketmaster
<%= submit_tag "Find Now" %>
<% end %>
<% #shows.each do |show| %>
<%= show.title %> |
<% show.tickets.each do |ticket| %>
<%= ticket.store %><br />
<% end %>
<% end %>
show.rb
class Show < ActiveRecord::Base
has_many :tickets
end
ticket.rb
class Ticket < ActiveRecord::Base
belongs_to :show
end
When I wrote something in the search_field, checked the "check_box" and clicked "Find Now" button, the log showed like below;
Parameters: {"utf8"=>"✓", "q"=>{"title_cont"=>"something", "shows_tickets_store_cont"=>"venue"}, "commit"=>"Find Now"}
Show Load (1.1ms) SELECT DISTINCT `shows`.* FROM `shows` INNER JOIN `tickets` ON `tickets`.`show_id` = `shows`.`id` WHERE (`shows`.`title` LIKE '%something%') LIMIT 25 OFFSET 0
I have no idea why the SQL doesn't have WHERE clause for Ticket.store, in spite of ticket controller received "shows_tickets_title_cont"=>"venue".
Please, suggest solution for this.
Thanks in Advance.
Actually the problems is because your second key is: shows_tickets_store_con but is should be shows_tickets_store_cont. It accepts attribute if it has predicate _cont.
Ransack documentation:
https://github.com/ernie/ransack
cont (contains) and start (starts with) are just two of the available search predicates. See Constants for a full list.
# Edited 1
I made investigation a bit.
I do not think that your approach is good for your situation. If all the checkboxes are selected then you will have problems with your meta search - you have to set another predicate. In your situation it could be in predicate - because you use multiple values (checkboxes).
To have SQL like:
"shows_tickets_store" IN ('venue','something')
Possible predicates:
https://github.com/ernie/ransack/wiki/Basic-Searching
https://github.com/ernie/ransack/blob/master/lib/ransack/constants.rb
Also read this:
https://github.com/ernie/ransack/issues/20
https://github.com/ernie/ransack/issues/53

Resources