Displaying search bar query results from an API in Rails - ruby-on-rails

I am trying to create a simple app where you find games from an API via a search bar. I am using the Giant Bomb API gem (https://github.com/games-directory/api-giantbomb). The gem seems to be working since I can call things via the console. However, I am not quite sure how to display results or if there are problems with my search method (likely).
Here is my controller for Games:
class GamesController < ApplicationController
//Display search results
def index
#games = Game.all.order('created_at DESC')
#games = #games.search(params[:query]) if params[:query].present?
end
//Searches through API and redirects to results on index.
def search
#games = GiantBomb::Search.new().query(params[:query]).resources('game').limit(5).fetch
redirect_to index_path
end
private
def game_params
params.require(:game).permit(:name)
end
end
My search bar code on my home page:
<div class="search-font"><h1>Build your Collection</h1></div>
<div class="container">
<div class="row">
<div class="col-md-12">
<%= form_tag search_path class: "row", method: :get do %>
<div class="col-12 col-sm pr-sm-0">
<%= text_field_tag :game,
params[:game],
class: "form-control input-lg",
id: "typed-text" %>
</div>
<div class="input-group-btn ml-3">
<%= submit_tag "Search", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
</div>
And my index.html.erb where it is supposed to spit out the game names.
<ul>
<% #games.each do |game| %>
<li><%= game.name %></li>
<% end %>
</ul>
The search bar redirects but nothing is posted. In my console I can do search.query('Mario') then search.fetch to print out the results, but I am not sure how to use this function in my controller correctly.
[edit] Here are my routes as well.
Rails.application.routes.draw do
devise_for :users
resources :games
root to: 'pages#home'
get '/search', to: 'games#search', as: :search
get '/games', to: 'games#index', as: :index
end

redirect_to creates a new request, you need to use render as in...
render 'index'
That way you can use your #games variable in the view

Related

Missing required keys: [:id] - Routing to a view for each instance of my model with its unique ID

I'm working on a job board to learn/practice rails. I have a separate view for each job category, and I want the user to be able to click on a particular job posting to access another view with all of the listing's details. I've partially figured out the routing, as I'm able to go to localhost:3000/jobs/listing/7 for example to see the view for the listing of id:7. I'm having a problem linking to the /listing/:id from my job category view, and can only access a view for a specific id by typing it into the address bar. I've been working on this for days and checked out many related questions on here, but can't seem to figure it out. I believe I'm overlooking a simple, but critical detail, since i'm not very experienced with rails.
Here is my job category view:
<div class="cat-banner" id="developer">
<h1>Human Resources Jobs</h1>
<h4 class="listing-count"><%= Job.where(:category => 'Human Resources').count.to_s + ' Listings' %></h4>
</div>
<div class="category-page">
<!-- Full-Stack Developer Jobs -->
<div class="jobs-posted">
<hr class="other-line">
<% if Job.where(:category => 'Human Resources').count > 0 %>
<% #jobs.each do |job| %>
<div class="job">
<% if job.category == "Human Resources" %>
<span class="job-logo"><%= image_tag('salesforce.png', :size => "60x40") %></span>
<span id="line-align"><p class="title"><%= link_to job.title, listing_path(#job) %> </p>
<p class="name"><%= job.name %></p></span>
<% if job.location == "Remote" %>
<span class="remote-tag"><%= job.location.upcase %></span>
<% else %>
<p class="location"><%= job.location %></p>
<% end %>
<p class="kind"><%= job.kind %></p>
<p class="time-stamp"><%= job.created_at.strftime("%A, %B %d %Y") %></p>
<hr class="line">
<% end %>
</div>
<% end %>
<% else %>
<p>There are no human resources jobs at the moment...</p>
<p style="text-decoration: underline;"><%= link_to 'Post a Human Resources Job Here', new_job_path %></p>
<% end %>
</div>
<!-- End of Human Resources Jobs -->
</div>
And my routes.rb file:
Rails.application.routes.draw do
get 'subscribers' => 'subscribers#index'
get 'jobs/remote' => 'jobs#remote'
get 'jobs/listing/:id' => 'jobs#listing', as: 'listing'
get 'jobs/company' => 'jobs#company'
get 'jobs/dev' => 'jobs#dev'
get 'jobs/design' => 'jobs#design'
get 'jobs/marketing' => 'jobs#marketing'
get 'jobs/ai' => 'jobs#ai'
get 'jobs/fullstack' => 'jobs#fullstack'
get 'jobs/frontend' => 'jobs#frontend'
get 'jobs/backend' => 'jobs#backend'
get 'jobs/it' => 'jobs#it'
get 'jobs/software' => 'jobs#software'
get 'jobs/product' => 'jobs#product'
get 'jobs/cloud' => 'jobs#cloud'
get 'jobs/mobile' => 'jobs#mobile'
get 'jobs/database' => 'jobs#database'
get 'jobs/datascience' => 'jobs#datascience'
get 'jobs/blockchain' => 'jobs#blockchain'
get 'jobs/security' => 'jobs#security'
get 'jobs/support' => 'jobs#support'
get 'jobs/network' => 'jobs#network'
get 'jobs/finance' => 'jobs#finance'
get 'jobs/sales' => 'jobs#sales'
get 'jobs/hr' => 'jobs#hr'
get 'jobs/businessdev' => 'jobs#businessdev'
resources :jobs
root 'jobs#index'
get 'jobs/index'
get 'jobs/new'
And part of the Jobs Controller:
class JobsController < ApplicationController
def index
#jobs = Job.all
#subscribers = Subscriber.all
end
def new
#job = Job.new
end
def listing
#job = Job.find(params[:id])
end
def show
#job = Job.find(params[:id])
end
def create
#job = Job.new(params.require(:job).permit(:title, :url, :category, :kind, :location, :description, :name, :summary, :website, :email, :companyDescription, :headquarters ))
if #job.save
redirect_to root_path
else
render "new"
end
respond_to :html, :json
end
I've tried:
<%= link_to job.title, listing_path(#job) %>
<%= link_to job.title, listing_path(#job.id) %>
<%= link_to job.title, listing_path(#job[:id]) %>
<%= link_to job.title, listing_path %>
and other variations that I thought would work from reading StackOverflow
I believe my problem comes from this link_to statement (wrong syntax?), as everything looks alright in my jobs controller and routes file.
I either get:
No route matches {:action=>"listing", :controller=>"jobs", :id=>nil}, missing required keys: [:id],
or
undefined method `id' for nil:NilClass,
or
undefined method `[]' for nil:NilClass
The "missing required keys: [:id]" error is confusing me. I've checked out many resources trying to figure out how to pass the :id but can't solve it.
This is my first post on here and I REALLY appreciate any help and look forward to being knowledgeable enough in the future so I can answer questions too.
rake routes
The view that you are putting as example is using the instance variable #jobs. According with your controller that would be your index action where you don't have #job defined
Note: Notice on that view you are using #jobs and job on your iterator
So I think if you change #job for job that would fix the problem on that view
<%= link_to job.title, listing_path(job) %>
As the error clearly states, your path is expecting a job id but it is not getting one, so inspecting your call for the path, in line:
<span id="line-align"><p class="title"><%= link_to job.title, listing_path(#job) %> </p>
you are passing #job as param to the listing path.
change it to job so it would be:
<span id="line-align"><p class="title"><%= link_to job.title, listing_path(job) %> </p>
For the missing id, you should do:
<%= link_to job.title, listing_path(id: #job) %>
since your id is stored in the variable #job
It seems that the reason this isn't working is because you are not sending the correct argument to your link_to here:
<%= link_to job.title, listing_path(#job) %>
You have to remember that you are iterating through all your #jobs and calling each individual job with the job variable between the | |. You are trying to create a link to each individual job, so the correct link_to should be:
<%= link_to job.title, listing_path(job) %>
Where job is the individual job that the link_to is looking for.

Search on Welcome Controller

I have a Product (imovel) controller where the users can create his own Products (imovels). I am using devise for the authentication and the CRUD (create, Update, Delete) needs login. So for the clients be able to see the products and doesn't need a user, I created the Welcome controller where so it is the root.
In the Index of the Products I use Ransack to do the research in the table and works just fine. (very happy about it).
On the welcome controller I try to do the same thing, but when I submit the search the page gets redirect to the imovels#index.
Controller:
class WelcomeController < ApplicationController
def index
#q = Imovel.ransack(params[:q])
#imovel = #q.result(distinct: true)
end
end
View:
<div class="container text-center">
<%= search_form_for #q do |f| %>
# Search if the name field contains...
<%= f.label :descricao_cont %>
<%= f.search_field :descricao_cont %>
<%= f.submit "Pesquisar", class: "btn btn-primary" %>
<% end %>
</div>
Another thing that can be important in the index (imovels#index) there is a for in a tr and the information is filtered there:
Imovels Index
<tbody>
<% #imovels.each do |imovel| %>
<tr>
<td><%= imovel.id %></td>
<td><%= imovel.descricao %></td>
<% end %>
And in the welcome controller where I need the search, I used Divs:
Welcome Index
<% #imovels.each do |imovel| %>
<div class="card">
<div class="containerImovel">
<h4><b><%= imovel.descricao %></b></h4>
<p><%= imovel.cidade %> - <%= imovel.bairro.nome %> </p>
</div>
</div>
<% end %>
How can I do the search on the divs of welcome controller? Ransack is the better option for it? It is possible to search in the has_many :through association?
Add a path for it in your routes.rb
resources :imovel do
collection do
match 'search' => 'welcome#search', via: [:get, :post], as: :search
end
end
and then add a new controller action to WelcomeController
def search
index
render :index
end
and afterwards modify the search form like so
<%= search_form_for #q, url: search_imovel_path, html: { method: :post } do |f| %>
Be sure to recheck the naming/variables as I'm not completely familiar with your app

Ruby on rails. Mailboxer, move multiple conversations to trash. Undefined method for #<Array

I am struggling with sending multiple items to the trash folder using checkboxes. I get an
undefined method `move_to_trash' for #<Array:0x007...etc...
move_to_trash works fine on single conversations.
I have a checkbox next to each conversation rendered by a partial, and a button to delete all checked conversations.
Anyway, my conversations controller:
def trash_multiple
#convo = mailbox.conversations.find(params[:trash_id])
#convo.move_to_trash(current_user)
redirect_to mailbox_inbox_path
end
The checkbox which is in a partial, placed next to each conversation:
<%= check_box_tag "trash_id[]", conversation.id %>
The id's are correct.
The form:
<div class="message-cont">
<div class="col-md-8">
<%= form_tag trash_multiple_conversations_path, method: :post do %>
<%= submit_tag "Trash selected" %>
<div class="panel-body">
<% if is_conversation %>
<%= render 'conversations/form' %>
<% else %>
<div class="msg-cnter">
<%= render partial: 'conversations/conversation', collection: messages %>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
And my routes:
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
collection do
get :trashbin
post :empty_trash
post :trash_multiple
end
end
Any hints on getting this to work for an array would be greatly appreciated, thanks.
SOLUTION:
changing controller to:
def trash_multiple
params[:trash_id].each do |element|
#convo = mailbox.conversations.find(element)
#convo.move_to_trash(current_user)
end
redirect_to mailbox_inbox_path
end
as stated by #wpp has fixed this.
move_to_trash works fine on single conversations.
My guess is that you want to invoke the move_to_trash method on each element of the array:
array.each do |element|
element.move_to_trash
end
or shorter:
array.map(&:move_to_trash)
Try this
#convo.each {|c| c.move_to_trash(current_user) }

Using partial with paper trail

I'm trying to put some code in a partial from my show page in /events. The code works fine when I use it in my show page, but when i extract it to a partial I'm getting a No Method Error
undefined method `event' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_PaperTrail_Version:0x007f4368823a68>
versions/_version.html.erb
<% cache version do %>
<div class="feed-item">
<h4>
<%= link_to version.item.name, version.item %>
<small>
<%= version.event + "d" %> by <%= link_to User.find(version.whodunnit).username, User.find(version.whodunnit) %>
</small>
</h4>
<ul class="list-unstyled">
<% version.changeset.each do |data| %>
<li>
<strong><%= data[0].capitalize %>:</strong>
<% if data[1][0].present? %><p class="red">- <%= data[1][0] %></p><% end %>
<p class="green">+ <%= data[1][1] %></p>
</li>
<% end %>
</ul>
</div>
<% end %>
show.html.erb
<%= render :partial => '/versions/version', :object => #versions %>
events controller
def show
#versions = #event.versions
end
events model
has_paper_trail
Any idea how i could put my code in a partial instead of having it inside my show view? Thanks.
EDIT:
I still get a No Method Error
undefined method `item' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_PaperTrail_Version:0x007f43688ee1a0>
events_controller.rb
before_action :set_event, only: [:show, :update, :destroy]
def set_event
#event = Event.find(params[:id])
end
Do you have defined the #eventvariable in the eventscontroller?
The #event.versions method has to be called on an actual event object.
For example
def show
#event = Event.find(1)
#versions = #event.versions
end

Couldn't find <object> without an ID Rails

I am trying to ensure that each job has the correct link when a user clicks on it.
The issue I am having is that I keep getting the error Couldn't find job without an ID.
In my view I have the following code:
<% #jobs.group_by{|x| x.created_at.strftime("%d %b. %Y")}.each do |date,jobs_on_that_date| %>
<section class="date"><%= date %></section>
<section id="top-job">
<% jobs_on_that_date.each do |job| %>
<section id="job-wrapper">
<%= link_to url_with_protocol(#link.job_url), :target => '_blank' do %>
<section id="job">
<%= job.title %> - <%= job.company %>
<%= job.salary %>
<%= job.location %>
<%= job.job_type %>
</section>
</section>
<% end %>
<% end %>
</section>
<% end %>
In my controller I am creating an object called #link as follows:
def index
#user = current_user
#jobs = Job.where('created_at > ?', 30.days.ago).reverse
#link = Job.find(params[:id])
end
Finally I have the following Routes setup.
JobappV2::Application.routes.draw do
devise_for :users
resources :jobs
resources :users do
resources :jobs
end
root :to => 'jobs#index'
end
If I use #link = Job.find(2) this works but every job ends up with the link input by the job with id 2.
Thanks in advance for any help!
what is params[:id]?
I suspect that if you do raise params[:id].inspect in your controller, you will find it's nil. Besides, what's the point in creating #link? just put job.job_url in your view instead of #link.job_url

Resources