What action after "submit"? - ruby-on-rails

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.

Related

Rails - calling a method in controller using link_to

I'm trying to call a method in controller from my index.html file while staying on the same path... is it possible... can anyone help me
index.html
<%= link_to "Click", controller: "products", action: "click" %>
controller.rb
def click
puts "click called!!!"
end
routes
get 'click'
Error: Missing :controller key on routes definition
Per the documentation of Rails Routes, you got to specify the controller and the action where it is routed, in your case the Products controller within the click action.
So in your routes.rb file your proper get syntax should include the destination, like this:
get '/products/:id', to: 'products#click'
Also in your link_to you should include the ID of the product so the routing passes the id to the controller and you should include logic in your controller to manipulate that ID how you need. See this.
PS: Don't name your action click , name it as the actual action to perform on a product, like show. Please also check what Resources routing is.

Rails does not navigate to controller method

I am trying to add a new controller method. I also created a corresponding view for the same. All I am trying to do is create a variable called #x and printing it in the view. I am doing this just to verify if my application is going into the method. However, I do not see the value getting printed on the view. Please help.
This is my controller named submitted_content_controller.rb
class SubmittedContentController < ApplicationController
def begin_planning
#x = 1
end
end
This is my view called begin_planning.html.erb
<%= form_tag url_for(:action => :revision_planning), method: "post" %>
<%= text_field 'questionnaire', 'name', class: "form-control width-250" %>
<p><%= #x %></p>
<button>Create</button>
This is the routes I added:
get :begin_planning
When I am in the begin_planning html page, I see the text field and create button but I don't see the value of #x getting printed. It will be a huge help. Thank you.
This is my routes output:
begin_planning_submitted_content_index GET /submitted_content/begin_planning(.:format) submitted_content_controller#begin_planning
there are other routes to which I didn't add, because this controller has many other methods which I did not add since it's a huge file.
You may be rendering the view without going through the action.
If Rails finds a view file with a name that matches a route, but doesn't find a corresponding action for that route, it will still
render the view.
https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action
So, you successfully render the form in the view, but Rails
doesn't know what #x means.
In your routes file, try adding the following outside of any namespaces:
get '/begin_planning', to: 'submitted_content#begin_planning'
Your rake routes should include the following:
begin_planning GET /begin_planning(.:format) submitted_content#begin_planning
And navigate to http://localhost:3000/begin_planning
Or,
if you'd like to namespace, you can add the following to your routes file instead:
namespace :submitted_content do
get :begin_planning
end
And your 'rake routes' should include the following:
submitted_content_begin_planning GET
/submitted_content/begin_planning(.:format)
submitted_content#begin_planning
And navigate to http://localhost:3000/submitted_content/begin_planning

Rails 5: Button to trigger controller method

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.

undefined method `pushes_path' for #<#<Class:0x007f85a15c6c90>

i'v been trying to resolve this error for the past 5 hours and I'm gonna burn my computer if I can't solve this.
undefined method `pushes_path' for #<#:0x007f859d605250> this is the error code I'm getting but i don't understand why.
this is my index.html.erb file inside of the interaction
<%= simple_form_for #push do |f| %>
<%= f.input :payload, as: :text %>
<%= f.input :segment, as: :radio_buttons %>
<%= submit_tag "start the campaign" %>
<% end %>
and this is my interaction controller
class InteractionController < ApplicationController
def index
#push =Push.new
end
end
Push is my table in the database and i'll get the inputs and write them in the database to use them for later one.
and this is my routes file
devise_for :partners
get 'home/index'
get 'segmentation/index'
get 'interaction/index'
root to: "home#index"
i really don't know why its looking for pushes_path, what am i doing wrong?
form_for
The problem you have is that your form_for method is going to try and generate a route based off your #path object. And as such, if you don't have a path created for it, you'll receive the error you're getting:
:url- The URL the form is to be submitted to. This may be represented
in the same way as values passed to url_for or link_to. So for example
you may use a named route directly. When the model is represented by a
string or symbol, as in the example above, if the :url option is not
specified, by default the form will be sent back to the current url
(We will describe below an alternative resource-oriented usage of
form_for in which the URL does not need to be specified explicitly).
The bottom line is that as Rails is object orientated, its built around the assumption that you'll have routes set up to handle the creation of individual objects.
Every time you use form_for, Rails will attempt to construct your routes from your object -- so if you're trying to do the following, it will treat the routes as photo_path etc:
#app/views/pushes/new.html.erb
<%= form_for #push do |f| %>
...
<% end %>
--
Fixes
As #mandeep suggested, there are several fixes you can employ to get this to work:
Firstly, you can just create a route for your push objects:
#config/routes.rb
resources :pushes
Secondly, as you're using a different controller, you'll want to do the following:
#config/routes.rb
resources :interactions
#app/views/pushes/new.html.erb
<%= form_for #push, url: interaction_path do |f| %>
...
<% end %>
This will route your form submission to the interactions controller, rather than the pushes controller that you'll get by default!
Objects
Something to consider when creating Rails-based backends is the object-orientated nature of the framework.
By virtue of being built on Ruby, Rails is centered on objects - a term for a variable, which basically encompasses much more than just a piece of data. Objects, in the case of Rails, are designed to give the application:
Once you understand this, the entire spectrum of Rails functionality becomes apparent. The trick is to realize that everything you do in Rails should be tied to an object. This goes for the controllers too:
--
Ever wondered why you call resources directive in your routes, for a controller? It's because you're creating a set of resourceful routes based for it:
Do you see how it's all object orientated?
This gives you the ability to define the routes for specific controllers etc. The most important thing to note is how this will give you the ability to determine which routes / controller actions your requests should go
--
There's nothing wrong in using the controller setup as you have - the most important thing is to ensure you're able to define the custom URL argument, as to accommodate the non-object based structure
In your index action you have
def index
#push =Push.new
end
and your form has
<%= simple_form_for #push do |f| %>
so your form is looking for /pushes with post verb or pushes_path and you don't have that route in your routes.rb file so to fix this you need to add this in routes.rb:
resources :pushes
Update:
when you add resources :push rails basically creates seven different routes for you. One of which is
POST /pushes pushes#create create a new push
and if you look at the html generated by your form it would be something like:
<form action="/pushes" class="new_push" id="new_push" method="post">
// your fields
</form>
notice the action and verb so when you submit your form your routes are checked for them and since you didn't define them in your routes you were getting this error
And how will i be able to use the params i m getting from this form with this new resource addition?
Your form will take you to pushes_controller create action so first of all you'll have to define them. You can access them simply by params[:pushes] in your controller action but since you want to create a new record so you'll have to permit those attributes, checkout strong parameters
If you are using rails >= 4 then you can do
class PushesController < ApplicationController
def create
#push =Push.new(push_params)
if #push.save
redirect_to #push
else
render 'interaction/index'
end
end
private
def push_params
params.require(:push).permit(:attributes)
end
end
If you are using rails < 4 then instead of permitting these attributes(because strong parameters feature came from rails 4) you'll have to tell rails that these attributes are accessible by writing this in your pushes.rb
attr_accessible :attribute_name
Why it is assuming that its pushes controller?Because of the Push.new creation?
That's because if you look at your index action #push = Push.new so #push contains a push object with nil values(as you have just initialized it) so this is where rails magic comes, rails automatically tries to figure out url of your form and since your #push is only an initialized variable so rails takes you to create action for it. For details you should checkout rails polymorphic urls If you want your form to go to interaction_controller or some other url then you'll have to specify the url option for it
<%= form_for #push, url: "your_url_for_custom_method" %>
// other fields
<% end %>
And in the end you should really read docs

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