RESTful way to use form_for? - ruby-on-rails

I am attempting to use form_for to implement a search form that works with a table-less Search model I created. The search form keeps triggering the 'index' action. I assume I should use 'new' to create the form and 'create' the process the search query. Looking at the log, my POST is getting changed into a GET. Here's my code:
/searches/new.html.erb:
<% form_for :searches, #search, :url => searches_path, :html => {:method => :post} do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :keywords %><br />
<%= f.text_field :keywords %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
What's the standard way for triggering the 'create' action with form_for?

Are you using the RESTful map.resources :searches ?
If so, shouldn't your :url be set to new_search_path ?

form_for is used with models. For a simple search form, I reccommend doing something like this:
<% form_tag posts_path, :method => :get do |f| %>
<%= f.text_field :query %>
<% end %>
You'll get /posts?query=wtf.

Related

Rails view submit parameter to controller method defined by me

How can I write a form in the view which calls a controller method I've defined? Also, I want to pass a parameter to the method. I want to do something like this, where I have defined the method predict, which takes the parameter days.
<%=form_for #currency, url: url_for(:controller => :currencies, :action => :predict) do |f| %>
<%= f.label :days %><br />
<%= f.text_field :days %>
<%= f.submit "Predict", class: "btn btn-primary" %>
<%end%>
Also, what do I need to add in routes.rb?
The 'rails way' would say not to create custom actions but create a new Predictions controller and use a standard :new or :create action depending on what you want.
That being said, you can use
<%=form_for #currency, url: {action: "predict"} do |f| %>
<%= f.label :days %><br />
<%= f.text_field :days %>
<%= f.submit "Predict", class: "btn btn-primary" %>
You can find it in these docs by searching for "action:" http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for
You'll then have access the params[:days] or however you set up your strong params. Hope this helps!
I generated a scaffold Currency with only one column (days) :
rails generate scaffold Currency days:string
In my Currency controller you have two action (home for the form and the root path and predict) :
class CurrenciesController < ApplicationController
def home
#currency = Currency.new
end
def predict
puts params[:currency][:days]
redirect_to root_path
end
end
The home view with the form looks like this :
<%= form_for #currency, :url => url_for(:controller => 'currencies', :action => 'predict') do |f| %>
<%= f.label :days %><br />
<%= f.text_field :days %>
<%= f.submit "Predict", class: "btn btn-primary" %>
<% end %>
With this result you can see the days field printed in your console with the puts log.
My routes.rb looks like this :
get 'currencies/home'
post 'currencies/predict'
root 'currencies#home'

Using form input without updating model Ruby on Rails

I would like to put a form on one of my pages, but don't want to use form_for to update a model. I am basically using this like a filtering/searching system, where the user inputs something, and the page changes based on what the user input. I know this is a pretty simple problem, but I'm also a little new to Rails.
Note: I have the ability to filter the results if I can just get the input value. I just need access to the input value in my Controller.
Just use form_for with a symbol as argument rather than an instance variable.
You can access the form data in your controller by referencing your params, just like you normally would. Let's say you have a form kinda like this:
<%= form_for :search do |f| %>
<%= f.text_field :query %>
<%= f.submit %>
<% end %>
You'll then get the contents of the search form by calling params[:search][:query] in your controller.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for
you need meta_search
<%= form_for #search, :url => articles_path, :html => {:method => :get} do |f| %>
<%= f.label :title_contains %>
<%= f.text_field :title_contains %><br />
<%= f.label :comments_created_at_greater_than, 'With comments after' %>
<%= f.datetime_select :comments_created_at_greater_than, :include_blank => true %><br />
<!-- etc... -->
<%= f.submit %>
<% end %>

Simple_form can't find path for instance

I get this in my form:
undefined method `urls_path' for #<#<Class:0x000000048ec778>:0x00000005583090>
This is my form:
<%= form_for #url, :html => {:class => 'form-horizontal' } do |f| %>
<%= f.input :url %>
<%= f.input :contact_name %>
<%= f.input :contact_email %>
In my controller action I do, #url = Url.new
I have another app, that does things in the way way, so I don't know what's wrong with it.
Try to check your routes are correct, run
rake routes
you should see
urls GET / urls#index

Get the name of a parent resource when working with a nested resource

I have a comment controller that uses a form partial to add comments. Now this controller is nested under any parent resource that needs to have comments.
resource :post do
resource :comments
end
resource :poll
resource :comments
end
If I want to have a form partial that automatically configured for the proper resource how would I do it?
Right now I have to set up forms on the page of the nested resource like so:
<%= form_for [#post, #comment] do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
I would like to have a partial that looks something like the above code but that I can just call <%= render 'comments/form' %>
Any ideas on the best way to make this happen?
You can solve this problem by passing a local variable to the comments partial using the locals hash:
In your nested resource, lets say, post's view:
<%= render 'comments/form', :locals => {:resource => #post} %>
Your comments form :
<%= form_for [resource, #comment] do |f| %>
<%= f.label :title %>
<%= f.text_field :title %> <%= f.label :body %>
<%= f.text_area :body %> <%= f.submit %>
<% end %>
Also, I encourage you to go through this guide on partials where the details are explained.

Difference between :model and #model in form_for?

What is the difference between using form_for the following way:
<% form_for #user do |f| %>
<%= f.label :name %>:
<%= f.text_field :name, :size => 40 %>
...
<% end %>
and:
<% form_for :user, :url => {:action => 'create'} do |f| %>
<%= f.label :name %>:
<%= f.text_field :name, :size => 40 %>
...
<% end %>
Does using #user just automatically use CRUD methods for the URL actions?
If you just give a model instance like #user without specifying an action (as in your first example), Rails automatically uses the appropriate CRUD action for your form:
If #user is a new, unsaved User object, the form will point to your create action.
If #user is an existing User loaded from the database, the update action will be used instead.
This has the advantage that you can reuse the same form for both your edit and new views without changing the :url parameter for your forms.
As usual, the API docs provide more information.
If you give form_for a symbol without an instance variable it looks for an instance variable with the same name.
The documentation says:
For example, if #post is an existing
record you want to edit
<% form_for #post do |f| %>
...
<% end %>
is equivalent to something like:
<% form_for :post, #post, :url => post_path(#post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
...
<% end %>

Resources