Rails navbar conditional and getting No route matches in root_path - ruby-on-rails

Hello I want to show the search form inside the navbar only in the index page of products and the show page of the product. The thing is that it is showing on both the index page and the show page but when I click home to go to the root_path I get the following error:
No route matches {:action=>"show", :controller=>"products"} missing required keys: [:id]
How can I avoid that? This is my code in the application.html.erb:
<% if current_page?(products_path) || (product_path) %>
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="search_term" id="search_term">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
</div>
<% end %>

It would be better to just check the current controller.
<% if controller.controller_name == 'products' %>
You also have access to action_name if you wanna use that too
<% if controller.controller_name == 'products' && controller.action_name == 'show' %>

You can check for the product controller and action in order to achieve that. Checkout the below code.
if controller.controller_name == 'products' && %w(index show).include?(action_name)
For the action name in different ruby version have a look at Rails - controller action name to string
This will check for the product controller and both actions.

Related

How to capture a search term from a form and pass it to a method in Rails app

I am learning rails online and have got as far as creating a simple site with some products in a products table with fields:
id
name
price
description
I have gone to the getbootstrap site and started pinching the code from this example -
https://getbootstrap.com/docs/4.0/examples/jumbotron/
This page has a nice search box in the navbar at the top right. I now have it in my simple site and the container HTML currently looks like this:
<div class="container" >
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="#">My Shop</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="/">Products</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</div>
</nav>
</div>
My problem is that all of the tutorials I see are creating simple forms using ERB to implement some sort of search functionality. like so:
<% form_tag projects_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
While I want to utilise this nicely rendered HTML form instead.
I don't know how to capture the search term and pass it to a method from my form. The ERB example uses the params hash to store the search term.
What I would like to implement is -
1 - Capture the name of a product entered in the search box
2 - Pass that string to a method in my model that queries the DB for first matching name
3 - gets the record id and uses it to redirect to the Show page with the id to display the item
I have found that setting the form action to "/" causes a click on the submit button to jump to the index method in my controller. From there I am sure I could utilise the model to query the underlying DB but I cannot seem to pass across the search term.
I do have a params hash at that point but it just seems to have a "controller" and an "action" member. Is there an attribute I can set that would add the value to this hash?
Thanks in advance
Brad
You must set an action to the form and a name to the field
<form class="form-inline my-2 my-lg-0" action="/search" method="get">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search", name: "search>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
Then define the method in a controller.
StaticPagesController
def search
#search_term = params[:search]
end
And define your route in routes.rb
match '/search', to: 'static_pages#search', via: 'get'

Rails - get toggle-button status in controller

I did long research, but cannot find solution. I want to make a list of toggle-buttons in my form and then save ones checked by user. I know that I can named toggle-button and then find it in controller by params[:togglebutton-name], but it seems that toggle-button hasn't got any value. So for example I have 5 toggle-buttons, and user will check two of them. Then I want to know about it in Controller. What should I do?
toggle-buttons:
<% current_user.type_tags.each do |type_tag| %>
<button name="type<%= type_tag.id %>" id="associated-type-tag-<%= type_tag.id %>" type="button" class="btn btn-primary" data-toggle="button" aria-pressed="false" autocomplete="off">
<%= type_tag.name %>
</button>
<% end %>
Controller:
def create
#try = params[:type1]
render 'help'
end
Help:
Value: <%= #try %>;
And in result I have this:
Value: ;
I've already found the solution. I used btn-group with data-toggle: "buttons". Inside I have label and input with type=checkbox. That approach allows me to get a true value in my Controller if button is pressed. I can style the buttons on my own too.
I hope it will be useful for somebody.
<div class="btn-group" data-toggle="buttons">
<% current_user.type_tags.each do |type_tag| %>
<label class="btn btn-primary">
<input name="type<%= type_tag.id %>" id="associated-type-tag-<%= type_tag.id %>" type="checkbox" autocomplete="off">
<%= type_tag.name %>
</input>
</label>
<% end %>
</div>

Challenge with merging two params

I have following entry in my routes for subcategory**(a.k.a. type)** pages:
match '/jewellery/:taxon/(:tag)' => 'shop#index', :as => 'shop'
I also have a set of filters (type, material, plating etc) on the subcategory pages. So, consider a taxon "Earrings". I have following subcategories in this taxon - "Danglers", "Hoops", "Studs".
So, the corresponding subcategory pages are "/jewellery/earrings/danglers", "/jewellery/earrings/hoops" and "/jewellery/earrings/studs".
I want a functionality that if a user goes to sub-category page, the corresponding checkbox in the type filter should be checked. So, if I go to "/jewellery/earrings/studs" the checkbox labelled "Studs" should be checked by default. I want to allow multiple type selection, so input from filters needs to be an array. I have the following code:
<% Typelabels.each { |label| %>
<%if filter[:name] == "Type"%>
<% if (!params["type"].nil? && (params["type"].member? label))
or (!params[:tag].nil? && params[:tag].gsub(/[+-]/," ") == label.downcase)%>
<input type="checkbox" id='<%= label.to_s %>' name="type[]" value="<%= label %>" checked />
<label for="<%= label.to_s %>" class="<%= t %>_name_label"><%= label%></label>
<%else%>
<input type="checkbox" id='<%= label.to_s %>' name="type[]" value="<%= label %>"/>
<label for="<%= label.to_s %>" class="<%= t %>_name_label"><%= label%></label>
<%end%>
<% end %>
<%}%>
But challenge is that when I un-check the box "Studs" (which was checked by default, on "/jewellery/earrings/studs"), I get redirected to the same page as the tag in params is fixed.
Please can someone help me

Reading erb form fields, Rails4

Question about Rails4, I trying to retrieve the "Find Stuff" variable, in the erb form. This
is a search field, using zurb foundation - so the extra styling annotations floating around.
I don't have a model as this is just a form for reading the search input field - which is
in the tag, with placeholder as "Find Stuff".
To use normal Rails4 terminology, I would
like to pass the value of the "Find Stuff" field to the salutation controller, and I tried
many ways, but was unsuccessful, when I used render params[:post].inpect, it shows nil -the
variables that I pass to the controller, on clicking on the "Search" link_to, link. I tried adding an id field to the tag, and that too showed nil on render params[:post].inspect.
Any help, thanks in anticipation.
hello.html.erb form below.
<html>
<body>
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name">
<h1>Hello World!</h1>
</li>
<li class="toggle-topbar menu-icon"><span>Menu</span>
</li>
</ul>
<ul class="right">
<li class="has-form">
<div class="row collapse">
<div class="large-8 small-9 columns">
<input type="text" placeholder="Find Stuff" >
</div>
<div class="large-4 small-3 columns">
<%= link_to "", :controller =>
'salutation', :action =>'hello',
:class=>"alert button expand" %>
</div>
</div>
</li>
</ul>
</section>
</nav>
</body>
</html>
Controller follows
Salutation Controller follows
class SalutationController < ApplicationController
def new
#test = ''
end
def hello
#message = 'Hello World!'
#test = params[:Find_Stuff]
end
end
Wrap your search box in a form element, give your input a name and away you go. You can use the rails form helpers as well - see http://guides.rubyonrails.org/form_helpers.html which has a nice intro to creating a search form
<div class="row collapse">
<%= form_tag("/salutation/hello", method: "post") do %>
<div class="large-8 small-9 columns">
<%= text_field_tag(:find_stuff) %>
</div>
<div class="large-4 small-3 columns">
<%= submit_tag("Search") %>
</div>
<% end %>
</div>
Further to #slapthelownote's answer, the reason you're getting an error is because you're not passing any params to your controller
We've got something like what you want working at http://firststopcosmeticshop.co.uk (top search box) -- using a form_tag
If you want to see live code, I'll be happy to post!
Params
Using a form allows you to set various variables & then submit them to the controller as you've set them. I'd recommend using the form in the other answer, but to understand how it works, you need to read up on the Rails forms tutorial
Basically, the params hash is populated in the middleware of Rails -- from any data sent by HTTP to your backend
With links, you can only send GET params (domain.com/route&params=value), whilst with HTML forms, you can set POST params which are passed through the browser (not the URL)

Ruby on Rails jQuery Visual Effect

I am working on a search function on RoR that basically just has a cool visual effect when a user clicks the search button.
Here is the code in my view for search.rhtml
<html>
<head>
<title>Tutor</title>
<%= javascript_include_tag :defaults %>
</head>
<body>
<h1></h1>
<%= form_remote_tag :url =>{ :action => :search_results }, :update => "results" %>
<fieldset>
<legend>Tutor Search.</legend>
<label for="searchItField">Keyword Search.</label>
<input class="tfield" type="text" value="FIND YOUR TUTOR HERE" name="searchItField" id="searchItField" />
<span id="Submit_search">
<span id="Submit_search_hover"><input type="submit" id="Submit" value="Search" /></span>
</span>
</fieldset>
</form>
<div id="results">
</div>
</body>
</html>
Here is the search_results.rhtml which is what gets displayed in the results div in search.rhtml
<% for tutors in #tutors %>
<%= tutors.first_name %> <br/>
<% end %>
And finally here is my controller and actions.
class TutorsController < ApplicationController
def search
end
def search_results
#tutors = Tutors.find_by_sql('SELECT * FROM tutors')
end
end
What I want to do is basically create an effect that when the search results are loaded because of the ajax call that it would slide up. I am using jrails. Exactly how this site does it. http://keyonary.com/#/paste
In short, to get you started, you will need to do the following:
use observe_field on the input-field, which retrieves data from a controller-method and will update a certain div with the results
create a corresponding controller-method that will retrieve the items (use your search_results)
create a view for that controller-method that will show the data with the required effects and animation.

Resources