gallant
gallant

Reputation: 59

How do rails forms work without a model?

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

Answers (2)

Tekkla
Tekkla

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

mike.5551
mike.5551

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

Related Questions