Reputation: 59
I am trying to challenge my learning by creating a simple project using rails forms, however I have gotten really stuck and can't find any information that seems to help online.
What I am trying to do:
I want to create a rails application with no model (so no persistence of data). Simply put I want a user to enter a Soundcloud URL which then gets transferred to the controller where I can do more logic. Essentially I am really trying to understand the connection between the Rails form and the controller in rails. I have spent all day reading about HTML forms, as well as googling this exact question without really fully getting it.
I understand there are different form helpers, but what I cannot seem to understand is how to use these without a model. My biggest hang up right now is I cannot get the form values transferred to the controller. I thought I understood RESTful routes, PUT/GET etc.. but this has made me super frustrated that I cannot seem to get my head around this. Any advice is super appreciated.
The code:
Below is the specific code I am struggling with, currently when I get submit the form it crashes giving me an error based on routes, and that's where I am stuck.
Problem code is found in the _form.html.erb
file in views:
<%= form_tag '/show' do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
Routes.rb:
Rails.application.routes.draw do
resources :soundcloud_query
root 'soundcloud_query#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Error:
Routing Error
No route matches [POST] "/show"
rake routes output:
Prefix Verb URI Pattern Controller#Action
soundcloud_query_index GET /soundcloud_query(.:format) soundcloud_query#index
POST /soundcloud_query(.:format) soundcloud_query#create
new_soundcloud_query GET /soundcloud_query/new(.:format) soundcloud_query#new
edit_soundcloud_query GET /soundcloud_query/:id/edit(.:format) soundcloud_query#edit
soundcloud_query GET /soundcloud_query/:id(.:format) soundcloud_query#show
PATCH /soundcloud_query/:id(.:format) soundcloud_query#update
PUT /soundcloud_query/:id(.:format) soundcloud_query#update
DELETE /soundcloud_query/:id(.:format) soundcloud_query#destroy
root GET / soundcloud_query#index
Github link:
https://github.com/gaelant/simple_soundcloud_app/commit/09c4c4df524bb721a0f472b4378cd8c1ff18177f
Note: I understand this is a basic question but I have just gotten really confused with this. I know the way the code above is written is not correct, but I have tried so many different things and I just don't understand what is going on, or if this is even possible without a model.
Upvotes: 0
Views: 3188
Reputation: 76
Your /show
form action points to nowhere. rails routes
shows you which url is valid and to which controller#action
each of them lead.
The correct form action would be
<%= form_tag '/soundcloud_query' do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
A far more better way is to use the url_helpers available through your defined ressource in Routes.rb
Doing so your form action would look like this
<%= form_tag soundcloud_query_index_path do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
The hardcoded and the url_helper based solution will route your request to a controller class named SoundcloudQuery
where the action create
will be called. Inside this action you have to put all needed logic.
It's also possible do define that /show
should point to a specifc controller and action. This would look like this.
post '/show', to: 'mycontroller#myaction', as: 'mypathnameforhelper'
A much more better explanation with many examples about routes and how to use them can be found in this quite good guide.
Rails Routing from the Outside In
Hint: You should stay close to the ROR naming conventions. Controllers should have pluralized names. So you should define your routes like this:
Rails.application.routes.draw do
ressources :soundcloud_queries
root 'soundcloud_queries#index'
end
and then rename your controller class and file accordingly into SoundcloudQueries
and soundcloud_queries.rb
. But this is not mandatory.
Upvotes: 6
Reputation: 21
I think in this case you should not use the url in the form_tag but the controller action. Let's say you've got a view called my_form.html.erb and a submit_form method in your soundcloud_controller.rb
def submit_form
params[:soundcloud_url] your logic
end
I'd set up the routes like this:
get 'soundcloud_query' => 'soundcloud_query#my_form' // didn't want to use 'resources' but it doesn't matter
post 'soundcloud_query' => 'soundcloud_query#submit_form'
The form would then look like:
<%= form_for :this_doesnt_matter, action: :submit_form do |f| %>
<%= f.text_field :soundcloud_url %>
<%= f.submit %>
<% end %>
Upvotes: 1