Rails 5: Button to trigger controller method - ruby-on-rails

I use Rails 5 and MySQL.
I have an Imagecapturing page and want to make a button, when pressed, triggers a method call in my Imagecapturing controller. My attempt:
# imagecapturing index view:
<%= button_to "St. Gallen", action: "digitized_in_stgallen" %>
# imagecapturings_controller.rb
def digitized_in_stgallen
#imagecapturings = Imagecapturing.all.where("digitalisiert_in = 'St. Gallen'")
end
#config/routes.rb
Rails.application.routes.draw do
resources :imagecapturings
end
But I get an
No route matches {:action=>"digitized_in_stgallen", :controller=>"imagecapturings"}
How can I make a click on the button trigger the "digitized_in_stgallen" controller method?

You need to have a look at your routes file.
A quick fix is to update your routes file with this:
resources :imagecapturings do
collection do
get :digitized_in_stgallen
end
end
I'd really recommend having a quick look through the rails guides on routing here Rails Routing Guide. You may find using paths easier to maintain in the long run rather than declaring the controller action.

Related

Rails form builder with admin namespace

The code below works well to create new transactions on the Invoice show view. It however doesn't work when in admin namespace. i.e /admin/invoices/1/ but works on /invoices/1/
show.html.erb
<%= form_for([#invoice, #invoice.transactions.build]) do |form| %>
....
transactions form input
routes.rb
resources :invoices do
resources :transactions
end
When calling form_for in a namespace route like /admin/invoices/1/, Rails will automatically append admin to your route. In other words, form_for([#invoice, #invoice.transactions.build]) would POST to a route like /admin/invoice/:id/transactions/ rather than /invoice/:id/transactions/.
To fix, explicitly set the URL of the form and use a route helper method to infer the correct route:
form_for(#invoice, url: invoice_transaction_url(#invoice.id))
Note that you may need to replace invoice_transaction_url with the correct route. Use rake routes to find the helper method that corresponds to the desired controller POST action.

What action after "submit"?

In rails after pressing submit button in "new" I automatically come to "create" (similar after "edit" to "update"). All my params getting in "new" available in "create". This is by default.
If I have "export" instead of "new" and "process_export" instead of "create" - how reach similar effect?
If I get you right than you don't want to send the form to the default create action but rather to another, in your example to a process_export action.
All you have to do is to create a route in your routes.rb and set a custom form action url.
Example:
routes.rb
get '/process_export' => 'your_controller#export' # replace `your_controller` with your controller name
post '/process_export' => 'your_controller#process_export', as: :process_export
In your export view:
<%= form_for :resource, url: process_export_path do |f| %> <!-- Replace resource with your proper resource -->
<!-- Your form here -->
<% end %>
But I highly recommend you to observe the conventions of REST. It makes your live a lot easier.
Here are two resources which explain it in more detail:
Rails Routing: http://guides.rubyonrails.org/routing.html
Form Helpers: http://guides.rubyonrails.org/form_helpers.html
Rails follow the Convention over Configuration concept . The 7 methods of REST are automatically called from the controller when a similar request comes in the Rails 4 . For ex : the GET request will call new method , POST will call create method , DELETE will call destroy method etc .
Now , if you are creating a custom method in your controller like export and if you want to call it after the clicking on the submit button , you have to set routes accordingly in the routes.rb file . Which can be done as :
post "/chats" => "chats#export"
Here , chats is the controller and export is the method in that controller which you want to call on the submit action.
You can do :
$ > rails g scaffold Controller_name
and this will generate all the 7 REST methods in your controller automatically and similar routes are generated which you can check by doing :
$ > rake routes
I hope this helps.

Including attributes in custom Rails routes

I hope the title is not to misleading, as I don't know a better title for the problem I'm working on:
I have a doctor which belongs to location and specialty. I'd like to route to show action of the doc controller like this:
/dentist/berlin/7
I defined my routes like this:
get ':specialty/:location/:id', to: 'docs#show'
And in my views create the following url to link to the show action of the doc controller:
<%= link_to doc.name, "#{doc.specialty.name}/#{doc.location.name}/#{doc.id}" %>
Is this a good solution to the problem? If not, is there a cleaner way to construct urls like this possibly using resources? What the heck is the name for a this problem?
Thank your very much for your help in advance.
For references, you should have a look at this page (especially the end of section 2.6)
If it is only for a single route, it's okay as you did. But then if you want to have more than one route (like /dentist/berlin/7, /dentist/berlin/7/make_appointment, etc.) you might want to structure a bit more your routes so as to take advantage of rails resources.
For example, instead of
get ':specialty/:location/:id', to: 'doctors#show'
get ':specialty/:location/:id/appointment', to: 'doctors#new_appointment'
post ':specialty/:location/:id/appointment', to: 'doctors#post_appointment'
You could have something like this (the code is almost equivalent, see explanation below)
resources :doctors, path: '/:specialty/:location', only: [:show] do
member do
get 'new_appointment'
post 'create_appointment'
end
end
Explanation
resources will generate the RESTful routes (index, show, edit, new, create, destroy) for the specified controller (doctors_controller I assume)
The 'only' means you don't want to add all the RESTful routes, just the ones specified
Then you want to add member actions, ie. actions that can be executed on a particular item of the collection. You can chose different syntaxes
resources :doctors do
member do
# Everything here will have the prefix /:id so the action applies to a particular item
end
end
# OR
resources :doctors do
get 'new_appointement', on: :member
end
By default, the controller action is the same as the path name you give, but you can also override it
member do
get 'appointment', action: 'new_appointment'
post 'appointment', action: 'post_appointment'
end
Rails has some wonderful helpers when it comes to routing !
The correct approach is to give your route a name, like this:
get ':specialty/:location/:id', to: 'docs#show', as: 'docs_show'
Then you can use it like this:
<%= link_to doc.name, docs_show_path(doc.specialty.name, doc.location.name, doc.id) %>
Note 1:
Rails appends _path at the end of the route names you define.
Note 2:
You can see all the available named routes by executing rake routes.

Rails 4 Routing - undefined local variable

I have a payments table. In the index view I list all payments in a table and in the show view I'd like to show a form of all payments where a user can select which ones to further process.
Above the table in the index action view I have:
<%= link to "Customise", show_payment_path %>
Then in the controller:
def show
#payments = Payment.all
end
In my routes file:
resources :payments
The error I am getting is:
undefined local variable or method `show_payment_path'
I have tried
<%= link_to 'Customise Sepa Mandate', show_payments_path %>
as well but that gives the same error. As does using url instead of path.
The path for resourceful-routed show actions is just payment_path (singular resource) or payment_path(id). Your “customize” link would lead me to believe you actually want edit_payment_path(id), though.
See Rails Guides — Generating Paths and URLs From Code for more info.
Run rake routes command to see available routes and correct syntax.
Pass show_payment_path(:id) to get the particular payment show page.
for that make your own routes and create their own path variable such as
resources :payments, except: [:show] do
get '/show' => "payments#show", on: collection, as: :show
end

How do I create a rails controller action?

My rails app has a single CustomerSelectionController, with two actions:
index: which shows a form where the user can enter customer information and
select: which just displays a static page.
class CustomerSelectionController < ApplicationController
def index
end
def select
end
end
I've created an entry in my routes.rb file:
resources :customer_selection
and the form in the index view looks like:
<h1>Customer Selection</h1>
<%= form_tag("customer_selection/select", :method => "get") do %>
<%= submit_tag("Select") %>
<% end %>
however when I click on the Select button in the browser, all I get is:
Unknown action
The action 'show' could not be found for CustomerSelectionController
I'm not sure why it is trying to perform an action called show? I haven't defined or referenced one anywhere.
I'm not sure why it is trying to perform an action called show? I haven't defined or referenced one anywhere.
Yes you have. That's what resources does. It defines the seven default RESTful routes: index, show, new, create, edit, update and destroy. When you route to /customer_selection/select, the route that matches is "/customer_action/:id", or the "show" route. Rails instantiates your controller and attempts to invoke the "show" action on it, passing in an ID of "select".
If you want to add a route in addition to those, you need to explicitly define it, and you should also explicitly state which routes you want if you don't want all seven:
resources :customer_selection, only: %w(index) do
collection { get :select }
# or
# get :select, on: :collection
end
Since you have so few routes, you can also just define them without using resources:
get "/customer_selection" => "customer_selection#index"
get "/customer_select/select"
Note that, in the second route, the "customer_select#select" is implied. In a route with only two segments, Rails will default to "/:controller/:action" if you don't specify a controller/action.

Resources