I am trying to create a search function in Rails 4. I have it implemented properly and it is displaying the result I want, however it is also returning and displaying the entire database query - All columns from table including password digest etc. I have done this before but haven't run into an issue like this. Would like to know if I am doing something wrong.
here is my controller:
def index
if params[:search]
#pro = Admin.search(params[:search])
else
#pro = Admin.all
end
end
Admin Model:
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
And here is my views:
<%= #pro.each do |ind| %>
<ul>
<li><%= ind.name %></li>
</ul>
<% end %>
in Chrome, I see the returned name of the individual from the search, as I would like, plus meta data such as id: 1, admin_id: 2, name "", email: "", password_digest: "" etc. in an array format. This is what's stumping me, not sure why it's displaying this.
When I inspect the page in chrome, the array is just pasted right under the tags.
It goes away when I remove the entire .each method on #pro. Any insight anyone can provide is appreciated.
The line in view should be <% #pro.each do |ind| %>. If you're doing <%= %> the result is the actual #pro array, which is why you're getting it pasted under the tags.
Related
I am using an API gem with Rails(https://github.com/games-directory/api-giantbomb) so I can search through data. I got it working, however the data displayed has unnecessary text.
Here is my method that returns the search data:
def index
#games = GiantBomb::Search.new().query(params[:query]).resources('game').limit(100).fields('name').fetch
end
And it redirects to this page:
<ul>
<% #games.each do |game| %>
<li><%= game %></li>
<% end %>
</ul>
It displays the query data, however the result is something like this:
{"name"=>"Kirby Battle Royale", "resource_type"=>"game"}
I thought I would just get "Kirby Battle Royale", but it is showing other data as well. I assume this is because each individual "game" is the data being pulled from the search instead. So adding something like game.name doesn't work because the search code doesn't have a specific name attribute.
I looked through the documentation, and I thought #games = GiantBomb::Game.detail(:query) might work but then I get an undefined method for each.
I am not sure how to correctly define #games and where to put my search code.
I'm following Railscast: http://railscasts.com/episodes/37-simple-search-form?autoplay=true
The result shows well in my implementation. But because I have first_name and last_name columns instead of just "name" as in the example above, I need a way to search for both no matter what the search term is. How can I do this? Right now only first name search works.
user.rb
def self.search(search)
if search
where('first_name LIKE :search OR last_name LIKE :search', search: "%#{search}%")
else
all
end
end
people_controller, index function:
#users = User.search(params[:search])
index.html.erb (for people controller):
<%= form_tag people_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag("Search users", first_name: nil, last_name: nil) %>
</p>
<% end %>
<ul>
<% #users.each do |user| %>
<li>
<%= link_to profiles_path(user_id: user.id) do %>
<%= user.first_name %>
<%= user.last_name %>
<% end %>
</li>
<% end %>
</ul>
UPDATE:
So this is weird. I have 4 users. For the first 3, only first name search works. Last name or full name (or partial name) doesn't. For the last user, only last name search works.
...what could be going on? Just made three more users and tested. The first new user got searched only by first name. The second new user got searched by only last name. His first name is part of the last name of 3rd user, and that 3rd original user name was returned when searched by that new user's first name (...why? didn't work like this before; partial name search doesn't work for other users). And third user's last name only was searched.
UPDATE:
OK, didn't do anything. But now the first original's user gets searched by either last name or first name (only first name before). WHY? Second original user as well. And partial search for two users works now. WHY? And the last new user whose last name (only) was searchable is now not searchable by any. WHY?
And tried it again just now and returned to previous, searchable by first name only, no partial search, etc. Why is this keep changing? How can I make the search term simply search for either first name or last name or both?
UPDATE:
I got the answer (to the above, not in general). The search is CASE-SENSITIVE. Now my question is: how can I make it non-case-sensitive and have the search term that includes both first name and last name (eg "Tom Paulson") work? (right now only searching for either works)
UPDATE:
So I solved case sensitivity by changing LIKE to ILIKE. I'm using Postgres.
If you could help with searching for both first name and last name, I'd appreciate it!
UPDATE:
So I'm now using this to search for both or either first name and last name. But now partial search does not work. Is there a way to make that work here as well?
where("first_name ilike :search or last_name ilike :search or first_name || ' ' || last_name ilike :search", search: "%#{search}")
UPDATE:
Solved it by adding % to %#{search}
%#{search}%
The case seems resolved. Thank you! I will maybe post an answer later.
UPDATE:
ooh, you wanted to search in both columns.
one way is to use 'concat'.
assuming you put a space in between first and last name:
where("CONCAT(first_name, ' ', last_name ) ILIKE ?","%#{search}%")
FIRST ANSWER:
def self.search(search)
if search
buff=search.downcase
where('lower(first_name) LIKE ? OR lower(last_name) LIKE ?', "%#{buff}%", "%#{buff}%")
should be working.
or ILIKE if you prefer.
where('first_name ILIKE ? OR last_name ILIKE ?', "%#{search}%", "%#{search}%")
can you check the value of 'params[:search]' if it is not nil?
I am new to Rails, but slowly making progress. I can't quite wrap my head around how to achieve my next task.
I have a controller (IdeasController) with an index that looks like this:
def index
if params[:round].blank? && params[:challenge].blank?
#ideas = Idea.all.order(params[:sort])
# #ideas = Idea.all.order(created_at: :desc, cached_votes_up: :desc)
end
if params[:round].present?
#round_id = Round.find_by(name: params[:round]).id
#ideas = Idea.where(round_id: #round_id).order("created_at DESC")
end
if params[:challenge].present?
#challenge_id = Challenge.find_by(name: params[:challenge]).id
#ideas = Idea.where(challenge_id: #challenge_id).order("created_at DESC")
end
end
I am updating the view and filtering by category with the above :round and :challenge with the code below in my index.html.erb:
<%= link_to "All", ideas_path %>
<% Round.all.each do |round| %>
<%= link_to round.name, ideas_path(round: round.name) %>
<% end %>
<% Challenge.all.each do |challenge| %>
<%= link_to challenge.name, ideas_path(challenge: challenge.name) %>
<% end %>
Now, my problem is that I want to create a button that orders by created_at DESC or ASC. I want the button to essentially be a toggle. I also want another button to order by cached_weighted_average DESC or ASC. This is from acts_as_votable so I can sort by vote counts.
The problem I am running into is that I can create a link or button that orders by created_at or cached_weighted_average, but it replaces all of the URL that was previously filtered by :round or :challenge. For example, if a user clicks "Round 1" and sees all ideas marked for "Round 1" and then they click the link to order by cached_weighted_average, the URL replaces:
/ideas?round=Round+1
With this:
/ideas?sort=cached_weighted_average+ASC
What I want is:
/ideas?round=Round+1&?sort=cached_weighted_average+ASC
I know this is a very new question, but everything I have tried has failed so far. It feels like I am missing something very easy. What I noticed I can do easily is inside the controller I can do something like:
if params[:round].present?
#round_id = Round.find_by(name: params[:round]).id
#ideas = Idea.where(round_id: #round_id).order("cached_weighted_average DESC")
end
Which is perfect. This button just needs to switch between cached_weighted_average DESC and created_at DESC.
Any help is appreciated, thanks.
passing multiple parameters is one way to handle:
<%= link_to object.name, object_path(first: something, second: something_else) %>
then alter your conditionals to contemplate presence of multiple params.
to differentiate between round and challenge when attempting to allow the user to choose how they'd like to sort you could use the same name and then pass it different values.
something like:
params["round_or_challenge"]
this would change your conditional to something like:
if params["round_or_challenge"] == "round" && params["asc_or_desc"] == "asc"
# query
elsif params["round_or_challenge"] == "challenge"
# query
end
or whatever. it's basically the same...just pass the values you need. you can also pass the existing parameters from the view the same way you access them in the controller.
Thanks for the response, #toddmetheny. I didn't implement your solution, but your solution helped me understand passing multiple parameters a bit more.
I ended up creating a helper, sortable. I also used the url_for to append at the end of whatever the current URL might be. I liked this approach because it meant I could sort on any parameter. I'm not sure that it's the best solution, but it works.
def sortable (name, sort)
link_to name, url_for(params.merge(sort: sort))
end
I have a very simple, typical search form in rails. Input a string, and it checks a column for that model if any strings match it. A few weeks ago it was working just fine. I came back today, and suddenly doesn't work.
Here is my code. My search form:
<%= form_tag("/search/products", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
My Controller:
def search
term = params[:q]
puts "the term is #{term}"
#resultats = Product.search_products(term)
end
In my model, the search_products method:
def self.search_products(search_term)
if search_term == ""
return []
else
where("name LIKE ?", "%#{search_term}")
end
end
in the controller code, the puts "the term is #{term} prints the correct term every time. So I know that is being picked up correctly. just, when i search for something, it doesn't return the correct results. Here is a screenshot from my terminal:
"Les résultats sont" in the terminal means "the results are..." and then empty, because it returns nothing. What could be wrong here?
Your code currently searches for LIKE '%term' (string must end in term)
You probably need to have it search for LIKE '%term%' (string must contain term)
Just add a %:
where("name LIKE ?", "%#{search_term}%")
Why don't you do lower(?) and search_term.downcase to make sure its not case sensitive
I am trying to create helper method that displays the navigation. How ever my helper displays an array even though i am using content_tag. Was wondering if i was doing something wrong.
module SubscriberNavigation
def navigation
get_menu_items.find_each.map do |menu|
content_tag(:li, link_to("#{ menu.title.try(:capitalize) }", "#{ menu.url.downcase }"))
end
end
def get_menu_items
#get_menu_items ||= Subscriber::Menu.all
end
end
And when i display
<%= navigation %>
An array of records in being displayed. Instead of content_tag list items.
["<li>Contacts</li>", "<li>Terms and conditions</li>", "<li>About us</li>"]
I tried .html_safe etc but looks like i'm missing something.
It is returning an Array. You can try this:
<%= navigation.join(' ').html_safe %>