Rails, form that can work with different controllers - ruby-on-rails

I want to make erb template of searchbar that will call search method of its controller. Different controllers got same method, but will have different logic. Is it possible to make form that will work with every controller just by rendering it on their views?
--- UPDATE ---
I have found that kind of solution:
<%= form_tag "#{controller_name}/search", method: 'get' do %>
<div class="input-group">
<%= text_field_tag :sub_string, '', class: 'form-control', placeholder: "Search..." %>
<span class="input-group-btn">
<%= submit_tag 'Search', class: %w(btn btn-primary) %>
</span>
</div>
<% end %>
However when I hit the submit button, it goes to search action of my current controller and it thows an error:
Couldn't find Basis with 'id'=search
it tries to call set_basis private method, even if it is not called by before_action?

Set search form's controllers name with params[:controller].
Use Rails Guide to see how to pass controller and action for a form_tag or form_for.

I think you can
create the template/partial under views/shared folder
then in controller do something like
def search
render :partial => "shared/search"
end
Ok Then add this
in your partial so you can dynamically change your controller for the form
form_tag({controller: controller.controller_name, action: "search_action"}, method: "post", class: "form")

Related

rails one search field handled by two controllers

In my app I want to set a search form with two buttons. Each one of those buttons should send request to separate controller. Something like this:
<%= form_tag(products_path, method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<%= submit_tag 'First controller' %>
<%= submit_tag 'Second Controller' %>
<% end %>
Is this even possible? Or rails just impose on developer an "one form - one controller" way?
Use JavaScript to change the form URL based on the button clicked.
<%= form_tag(first_controller_path,id: 'search-form', method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<button type='submit' id="form-submit-button">First Controller</button>
<button type='button' id="second-controller-button">Second Controller</button>
<% end %>
<script>
$(function(){
$("#second-controller-button").on("click",function(e){
e.preventDefault();
var form = document.getElementById('search-form');
form.action = '<%= second_controller_path %>' ;
form.submit(); // Or you could also try document.getElementById("form-submit-button").click();
})
});
</script>
HTML5 added some attributes to INPUT and BUTTON elements. One of them is formaction so you can set the action triggered by each button independantly and it overrides the default form action.
<%= form_tag(products_path, method: :get) do %>
Search Field <%= text_field_tag :q %>
<br>
<%= submit_tag 'First controller' #triggers the default action %>
<%= submit_tag 'Second Controller', formaction: another_path %>
<% end %>
https://www.w3schools.com/tags/att_input_formaction.asp
You already defined form_tag with products_path through which the controller method is already defined.
So answering your question, you can't pass send requests to two different controllers with one form.
If you want to pass some status with buttons try adding some attributes to the buttons and differentiate them inside the controller.

Rails 5 simple search form just won't work

I have a navbar shared across all views by rendering it in application.html.erb with this form in it:
<form class="form-inline d-none d-lg-inline-flex">
<%= form_tag search_query_path, method: :get do |f| %>
<%= text_field_tag :query, params[:query], class: "form-control", placeholder: "Search" %>
<%= submit_tag "Search", name: nil %>
<% end %>
</form>
I want to search for similar titles in the Post model.
The methods are in the PostsController as follows:
def search_query
#results = Post.find_by_sql("SELECT * FROM posts WHERE title LIKE '%#{params[:query]}%'")
end
def search_query_params
params.require(:post).permit(:query)
end
private :search_query_params
The problem is: the search keeps getting processed by the current controller of the current view. If I'm the the index page (in the PagesController), the query takes place there, just reloading the url like this:
http://localhost:3000/?utf8=%E2%9C%93&query=test+title
I've tried everything and can't find where my logic is wrong.
These are the routes:
get '/search_query', to: 'posts#search_query', as: 'search_query'
form_tag generates a form element, so you are nesting a form inside a form here. Try deleting the outer form.

Rails link_to query params - selecting in item on the next page

Right now I have a link_to. It looks like a button the the user. It's an upgrade button so it routes the user to the plans page.
I not only want to route the user to the plans page but I want to pre-select the plan that supports the feature they are upgrading for. I was told that I could pass a query parameter into the link_to? Is the true and what does this look like in my situation? Here is my code.
LINK_TO
<%= link_to edit_account_plan_path, class: "button-big reverse-blue" do %>
HTML
<div class="plan-control">
<%= radio_button_tag :plan_id, plan.id, row.current?, disabled: row.ineligible? %>
</div>
you can pass a query parameter back to your controller something like this:
<%= link_to edit_account_plan_path(feature: 'basic'), class: "button-big reverse-blue" do %>
Then in your controller action routed by edit_account_plan_path, you can set an instance variable which you can use to preselect on your view page:
def edit
#plan = Plan.find_by(feature: params[:feature])
end
Then on your view page:
<div class="plan-control">
<%= radio_button_tag :plan_id, 'Basic', #plan.feature == 'basic' %>
</div>

Rails search form in different controller?

Okay say I have a simple search form for Projects records like in the railscast found here: http://railscasts.com/episodes/37-simple-search-form?autoplay=true
Can you put the form_tag for the search in a different view other than the projects index.html? Like in a static_pages controller type of deal view? And how could you redirect to the projects index.html view after submitting the search in such a case? Thanks
Add below code wherever you want to add search functionality.
<% form_tag projects_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
Changes needed in your controller only. Try render view instead of redirect and you are done.
def index
#projects = Project.search(params[:search])
render `projects/index`
end

How do I pass a parameter to a form partial that is shown via CSS?

So my form partial is loaded in my div id="secondary", which is hidden on first page load.
When the user hits a button with a class called toggleSidebar, then the _form.html.erb is shown.
I have overridden the partial to display a new form (even if update is pressed) when a user is not logged in like this:
<%= simple_form_for(Post.new, html: {class: 'form-horizontal' }) do |f| %>
As opposed to the regular version that looks like this, and is included in an if statement on this same partial:
<% if current_user and current_user.has_any_role? :editor, :admin %>
<%= simple_form_for(#post, html: {class: 'form-horizontal' }) do |f| %>
The real issue is in my view, when someone goes to Update, this is what happens when the user is logged out:
<%= link_to "Update", "#", class: "togglesidebar" %>
This is perfect, it executes the CSS and shows the empty form partial perfectly.
However, when a user is logged in, I want it to send the parameter parent_id: #post with the execution of the sidebar being toggled.
This is how it looks with a normal new_post_path view (i.e. the non-sidebar new post view):
<% if current_user %>
<%= link_to "Update", new_post_path(parent_id: #post) %>
<% end %>
This is what my PostController#New looks like:
def new
#post = Post.new(parent_id: params[:parent_id])
end
How do I either pass the params in the regular non new_post_path version, or tackle this another way?
You could probably use a helper method.
Just browse to the 'helper' directory under 'app' folder and create a file similar to [name]_helper.rb
In this file create a module by [name]Helper and declare your helper method in this module.
This module is automatically required by rails.
A small example might help you.
The code in the link_helper.rb under app/helper directory
module LinkHelper
def populate_link(link1, link2, parameter)
if current_user
public_send(link2, parameter)
else
link1
end
end
end
The code in views is
<%= link_to 'update', populate_link('#', 'new_requirement_path',parameter: 33) %>
I'm a bit confused by the question, but I think you may be just need to use a hidden field to pass the parent_id param back?
e.g./
<%= simple_form_for(Post.new, html: {class: 'form-horizontal' }) do |f| %>
<%= f.hidden_field :parent_id, { value: #post.try(:id) } %>
<% end %>
HTH?
I am also a bit confused, but the following railscast might help you. It shows how to embed data in an html-tag. You can probably do it the same way.
railscast-> passing data to javascript
Out of the possibilities there I'd recommend the data-attribute:
<%= simple_form_for,(Post.new, html: {class: 'form-horizontal' }, **data: {post_id: #post.id}**) do |f| %>
<% end %>

Resources