Rails CRUD Buttons for all views using single Partial - ruby-on-rails

Rails newbie here.
I would like to use a single partial to create my CRUD buttons on all views, regardless of controller. So this is what I have working so far. In my controller I have:
information_controller.rb
class InformationController < ApplicationController
before_filter :set
def set
#Set Paths
#new_path = new_information_path
#edit_path = edit_information_path
end
#Then normal index, show, etc definitions follows
end
I will take the index and edit pages as an example.
index.html.haml
-#operation = "index" #To let partial know what page it is in
-render 'form', operation: #operation
edit.html.haml
-#operation = "edit"
- render 'form', operation: #operation
Then, in my partial form I have:
_form.html.haml
.form-inputs
.container-fluid
.span8
.simple_form_for #foo do |f|
=f.input :title, as: :string
=render 'controls', f: f, operation: #operation
and in my controls form which serves only to display CRUD buttons regardless of the controller, I have:
_controls.html.haml
-if(operation=="new")
link_to "Create", #new_path, class: "btn btn-success"
-else
-if(operation=="edit")
=f.submit "Update"
-else
.span3
%table
%tr
%td=link_to "Edit", #edit_path(f), class: "btn btn-primary"
%td=link_to "Delete", f, confirm: "Are you sure", method: :delete, class: "btn btn-danger"
So this works well for the index page which loads 'edit, delete and create' buttons. But I do not know how I can properly assign edit_information_path in the controller to #edit_path because that requires an edit parameter 'f'.
The assignment #new_path = new_information_path works, but #edit_path requires 'f'. Any tricks?

Try this:
link_to "Edit",{:controller => params[:controller], :action => :edit, :id => f.object.id}, class: "btn btn-primary"
or:
link_to "Edit",{:controller => controller_name, :action => :edit, :id => f.object.id}, class: "btn btn-primary"

Related

Sending parameters through button on rails form_tag with put method

I have two links ( could be buttons if needed ) that say accept and decline and I need to send true or false parameters to my controller action by clicking one of those links. I don't want my parameters to be visible in the url so I need to use put method. I have tried with the link_to with defined method:
<%= link_to 'accept', { action: 'accept_offer', accept: true }, method: :put %>
<%= link_to 'decline', { action: 'accept_offer', accept: false }, method: :put %>
but my params are still visible.
I've tried using button_to but then my parameters are not passed.
What is the best way to determine which option has been chosen (accept or decline) without showing parameters in url?
my route has be defined like this:
put 'offers', to: 'offers#accept_offer'
i'll recommend to make a form instead of link_to and pass params in name. Use a form and POST the information.This might require additional code in source pages, but should not require logic changes in the target pages.
<% form_for #offer, :url => {:action => 'accept_offer'} do |f|%>
<%= submit_tag "", :value => "Accept", :name => "accept" %>
<%= submit_tag "", :value => "Decline", :name => "decline" %>
<% end %>
in your action you'll get params[:accept] or params[:decline] based on the link you clicked.
Edited to include commas and spaces with keyword arguments on submit tag.]
Start with just the conventional routes:
resources :offers
Then lets use button_to to create a discrete form:
<%= button_to 'accept', #offer, method: :patch, params: { "offer[accept]" => true } %>
<%= button_to 'decline', #offer, method: :patch, params: { "offer[accept]" => false } %>
The params option creates hidden inputs inside the form.
Then make sure you whitelist the correct attribute:
class OffersController < ApplicationController
def update
#offer = Offer.find(params[:id])
if #offer.update(offer_params)
redirect_to #offer, success: 'Offer updated'
else
render :new
end
end
def offer_params
params.require(:offer).permit(:accept, :foo, :bar)
end
end
If you need to have separate logic from the regular update then create two additional verbs:
resources :offers do
member do
patch :accept
patch :decline
end
end
<%= button_to 'accept', accept_offer_path(#offer), method: :patch %>
<%= button_to 'decline', decline_offer_path(#offer), method: :patch %>
This keeps your API restful and decriptive.

Routing rails Simple Search to a listings page

I have implemented a simple rails search which is searching my DB and displaying the results just fine. However, I am not fully understanding how to route my search query to a new page.
I have used rails scaffolding to create this particular section of my site:
class DogSearchesController < ApplicationController
before_action :set_dog_search, only: [:show, :edit, :update, :destroy]
# GET /dog_searches
# GET /dog_searches.json
def index
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
# GET /dog_searches/1
# GET /dog_searches/1.json
def show
#dog_search = DogSearch.find(params[:city])
end
index.html.rb
<%= form_tag dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
I have created a page in dog_searches/listing and added this to my Routes file as get 'dog_searches/listing'
Any help would be appreciated.
Commonly, search results will go to the index page with params. If you ever want to show a list of dog_searches, filtered or paged, it's a common approach to use the index action and view for all of this.
But, that said, if you want to render the listing page, you may want to set the form to that page
# routes.rb
resources :dog_searches do
get :listing, :on => :collection
end
In the view - notice the url change
<%= form_tag listing_dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
Then in the controller, you'd have a very similar action to index.
def listing
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
But again, can index handle all of this for you instead?
What is the directory where your form is, and which new page do you want to route your search query or result to?
By default, rails render the file with the same name as the controller action.
Therefore, if the controller action that is doing the search is the index action in DogSearchesController, then the view file is the dog_searches/index.html.erb
On the other hand, if you want the view to be dog_searches/listing.html.erb, then you may want to create a listing action in the DogSearchesController and move your search inside it as follow:
def listing
#dog_searches = DogSearch.where(["dog LIKE ? ","%#{params[:search]}%"])
end
and let your search form point to this action:
<%= form_tag listing_dog_searches_path, :method => 'get', :class => 'search-form' do %>
<i class="fa fa-map-marker"></i>
<%= text_field_tag :search, params[:search], :class => 'homesearch', :placeholder => 'Enter search term' %>
<%= my_button_to '<i class="fa fa-search"></i>', {}, :class => "fa fa-search" %>
<% end %>
Note here that I'm assuming that the path to the listing action is the listing_dog_searches_path.
Hope this throws some light into it?

Multiple link_to methods how to determine which one is clicked in controller

I've got multiple link_to methods in my view. Using the remote option true is there any way I can tell which link was clicked in my controllers update action?
Also, specifically I would like my link_to methods to call the update action in my controller which will increment or decrement the instance variable #lang, save the value in the DB, and then redirect back to the show action.
Here is what I have so far in my view file:
<div class="center hero-unit">
<%= #word.english %>, <%= #word.english_to_spanish %>
<%= link_to "Previous", "/langs/#{#lang - 1}", :method => :put %>
<%= link_to "Next", "/langs/#{#lang + 1}", :method => :put %>
</div>
Here is my langs controller:
class LangsController < ApplicationController
def show
#word = Lang.find(params[:id])
#lang = current_user.bookmark #bookmark keeps track in db for what word user is on
end
def update
#lang = #lang - 1
current_user.bookmark = #lang
current_user.save
render 'show'
end
end
Thanks for the help in advance!
To determine which link was clicked on your controllers update action, you can pass optional parameters:
<%= link_to "Previous", user_path(:id => #lang - 1, :option => 'previous'), :method => :put%>
<%= link_to "Next", user_path(:id => #lang + 1, :option => 'next'), :method => :put%>
Then, in your controller check params[:option] value.
Q: would the syntax in the controller be something like if params[:next] or something like if params[:option] == "next")
Actually, params[:option] == "next" is what you need to check the clicked link.
But if you prefer hipster-code style (like I am), you can do a trick:
class UsersController < ApplicationController
..
def update
if link_to(:next)
#'Next' link was clicked
end
end
def link_to(option)
params[:option] == option.to_s
end

Rails : Linking an anchor from a different controller/view

<%= link_to (:controller => "company_stuff", :action => "index", :anchor => :menu), :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
I am having difficulty linking a page which is on a different controller and also the link is an anchor. Basically the controller is called company_stuff the action is index and the anchor is called #terms
The problem was that the :controller :action :anchor was not being passed through as a hash, separate from the CSS class
Below is the solution
<%= link_to "Terms Of Use", {:controller => "company_stuff", :anchor => "terms"}, :class => "links" %>
I believe you can try something like this
<%= link_to index_company_stuff_path + "#terms", :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
Or
<%= link_to index_company_stuffs_path + "#terms", :class => 'links' do %>
<li>Terms of Use</li>
<% end %>
Depending on your controller name and route.
You can find more information on this question How to create an anchor and redirect to this specific anchor in Ruby on Rails

Add css class to rails link_to helper

I'm trying to style a rails link using css using the following code:
<%= link_to "Learn More", :controller => "menus", :action => "index", :class => "btn btn-inverse" %>
I would expect that this would create a link that looks like this:
Learn More
Instead, rails is rendering this -
Learn More
Has anyone else had this problem / know what I'm doing wrong? I know I can avoid this problem by manually creating the anchor tag rather than using helper, but I was wondering if there was a way to pass the css class info to the helper itself. I'm using Rails 3.2.6.
Thanks!
You have a syntax problem. Try this instead:
<%= link_to "Learn More", {controller: "menus", action: "index"}, class: "btn btn-inverse" %>
Some documentation for you to go further with the link_to Helper
They say:
Be careful when using the older argument style, as an extra literal hash is needed:
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
# => Articles
Leaving the hash off gives the wrong link:
link_to "WRONG!", :controller => "articles", :id => "news", :class => "article"
# => WRONG!
I recommend you to use the URL helper generated following your routes configuration. In your case:
link_to "Learn More", menus_path, :class => "btn btn-inverse"
A little reminder on the Helpers generated:
# routes.rb
resources :users
# any view/controller
users_path #=> /users
edit_user_path(user) #=> /users/:id/edit
user_path(user) #=> /users/:id (show action)
new_user_path(user) #=> /users/new
Try new argument convention:
<%= link_to 'Learn More', 'menus#index', class: 'btn btn-inverse' %>
if you do not have a controller action / route necessary for the link, you can pass nil as the placeholder and get the classes to apply as necessary
<%= link_to 'link verbiage', nil, class: 'classes for action tag'%>
I solved my problem by the way
<%= link_to image_tag("imageexamplo.png", class: 'class or id examplo css'),{controller: "user" , action: "index"}%>
This is how i solved it using another view engine, HAML just in case a fellow developer is having this need
%i= link_to "Add New Blog Post", user_post_edit_new_url(current_user), :class => "fa fa-plus-circle"

Resources