Rails - Simple Forms - undefined method `model_name' for nil:NilClass - ruby-on-rails

I am trying to make a form where you select tables that you want to export. I made a simple form with a list of tables that can be exported. My plan was to allow the user to toggle check boxes for the tables they want to export and as a result they would be able to download a zip file containing the tables.
Currently, when I try to go to the page with the form, I get an error:
undefined method 'model_name' for nil:NilClass
The majority of the usage of simple forms that I see online consists of using forms to create new items to save in their models. As a result, it seems that the line simple_form_for #example would mean that when the user clicks the submit button, there is a line in the controller such as #example = SomeClass.new". My understanding is that the user input of the form is saved in #example and can be used by the controller. However, as I am not creating a new item in the model, I just want to use the values from #example, I am not sure what to put in the controller to get rid of the error so that I can code the rest of the function in the controller.
Controller:
class FormController < ApplicationController
def index
#options = []
print(#options)
end
end
The form used:
<h2>Which tables do you want to export?</h2>
<div class="well">
<% tables_in_model = %w(Table1 Table2 Table3) %>
<%= simple_form_for #selected_options, :url => form_index_path, :method => :get do |f| %>
<%= f.input :options, as: :check_boxes, collection: tables_in_model %>
<%= f.button :submit, as: :Submit %>
<% end %>
</div>

As you said correctly in your question, simple_form should be used to render forms to the user when her actions are related to the creation or edition of ActiveRecord models.
For instance, when writing down code to enable a search feature, where your goal is to simply pass a bunch of user chosen params to a controller, you should not use it. I believe you are in a similar position with the feature you described.
Simple solution though: use rails form related DSL to get your form going!
Hope it's the answer you needed. Feel free to ask for more details if needed. Cheers!

i think you are using simple_form you need to specify like
#selected_options = SelectedOptionModel.new(params)
into your controller
then it passes into View.
if you don't have any model you can use form_tag
like this:
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
this will create html form like this:
<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="✓" />
<label for="q">Search for:</label>
<input id="q" name="q" type="text" />
<input name="commit" type="submit" value="Search" />
</form>

Related

Rails form using GET method regardless of what is specified

I have an HTML form intended to be used for password resetting. Its method is PATCH and it should be hitting the update method of the PasswordResetController. However, on submission, it is always make a GET request, regardless of the method specified. I can type method=ANYTHINGHERE and it always makes a GET request.
My form is simple:
<form class="group" action="<%= password_reset_url %>" method="PATCH">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
<input type="password" class="password-login" name="new_password" placeholder="New Password">
<input type="password" class="password-login" name="new_password_verify" placeholder="New Password Confirmation">
<button class="login-button">Reset Password</button>
</form>
My routes seem to be in order:
password_reset_index POST /password_reset(.:format) password_reset#create
new_password_reset GET /password_reset/new(.:format) password_reset#new
edit_password_reset GET /password_reset/:id/edit(.:format) password_reset#edit
password_reset PATCH /password_reset/:id(.:format) password_reset#update
PUT /password_reset/:id(.:format) password_reset#update
defined as resources :password_reset, only: [:new, :create, :edit, :update]
And my controller:
class PasswordResetController < ApplicationController
new, edit, create....etc.
def update
user = ...
end
end
Create, new, and edit all work perfectly fine, but it's not even getting into the update method when submitting the form. I just get No route matches [GET] "/password_reset/longTokenString. Any ideas? I feel like I've exhausted my options here.
This is not a duplicate of this question as the token string is being properly generated. The token string is also used as the id in the /password_reset/:id/edit route, and is working fine there as well.
Thanks in advance.
According to the rails strategy here is the clear explanation if what is the difference between the PUT and PATCH methods.
If you are coming from a previous version of Rails, you may be wondering why the update action of a RESTful route is mapped to the HTTP verb PATCH instead of PUT. In the HTTP standards document RFC 57892, it outlines that a PUT request to a given resource is meant to completely replace it on the origin server. However, when updating a resource in Rails, rarely, if ever, do you replace an entire resource when performing an update. For example, when updating an Active Record model, Rails sets the attribute updated_at timestamp, not the requesting client.
To follow better HTTP semantics, Rails will be using the HTTP verb PATCH for updates. PATCH allows for both full and partial updates of a resource, and is more suited to how Rails updates resources.If you are upgrading an existing Rails application, the HTTP verb PUT will still map to the update action in
RESTful routes, but it’s recommended to use PATCH moving forward.
I am going to explain how the User Edit option works in rails.
app/controllers/users_controller.rb
def edit
#user = User.find(params[:id])
end
The corresponding user edit view
app/views/users/edit.html.erb
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %>
Looking at the HTML source
<form accept-charset="UTF-8" action="/users/1" class="edit_user"
id="edit_user_1" method="post">
<input name="_method" type="hidden" value="patch" />
.
.
.
</form>
Note: Note here the hidden input field:
<input name="_method" type="hidden" value="patch" />
Form the Documentation:
method: (:get|:post|:patch|:put|:delete)
"In the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the form will be set to POST and a hidden input called _method will carry the intended verb for the server to interpret."
Reference: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
Hope so my explanation would be clear for understanding the concept. Happy Coding:)
According to the HTML standard, you can not add put as method for form. The only valid values for the method attribute are get and post. <form method="put"> is invalid HTML and will be treated like <form>, i.e. send a GET request.
You can also write form code by using rails form tag.
Some points to remember---
if you are making use of form_for tag,you dont have to worry about anything else because rails itself uses its Record identification to handle create(POST),new(GET) and update(UPDATE/PATCH) actions.
if you are not using form_for tag uniformly,which is your case,you must match the url exactly,So you need to pass the id too.
example:-
<form class="group" action="<%= password_reset_url(#your_model.id) %>" method="PATCH">
HOPE IT HELPS :)

Why does this form helper generate two inputs?

On a model, I have attr_accessor: :email_settings.
In a view, I have:
<%= form_for some_model do |f| %>
<%= f.fields_for :email_settings do |email_settings| %>
<%= email_settings.label :general, _("General updates") %>
<%= email_settings.check_box :general %>
General site updates
<% end %>
<% end %>
But in the HTML, this does not create one input for some_model[email_settings][general], it creates two. One hidden and one a checkbox:
<label for="user_email_settings_general">General updates</label>
<input name="user[email_settings][general]" type="hidden" value="0">
<input id="user_email_settings_general" name="user[email_settings][general]" type="checkbox" value="1">
General site updates
What's going on here? Why is there a hidden input and a checkbox for the same value, when I only want a checkbox?
Also in the controller action that the form is submitted to, I do this:
def update
puts "email_params: #{email_params}"
end
def email_params
params.require(:user).permit(:email_settings)
end
Which outputs:
Unpermitted parameters: email_settings
email_params: {}
Not sure how email_settings is being interpreted as "unpermitted" when I'm explicitly permitting it.
From the browser should always send a response.
If you do not select the box, will send the hidden field to understand that something has been sent.
In this way the rails will always receive an indication that the box was selected or not.
similar answer is here: Why does the check_box form helper generate two checkboxes, one hidden?

simple_form delete method instead post method

In simple_form is possible to use the http delete verb instead the default post verb?
<%= simple_form_for #object , method: :delete do |f| %>
<%= f.input :instance_name, as: :check_boxes, collection: #roles %>
<%= f.button :submit %>
<% end %>
It doesn't works.
Unfortunately simply stating that it doesn't work is not helpful in understanding the problem you're seeing, but I'll make a guess based on my own initial confusion with the "method:" parameter. Most browsers don't support PUT and DELETE methods, so what simple_form_for does is generate a form with a POST method, but it also adds a hidden field to pass the actual method. So:
simple_form_for #service, url: service_path, method: :delete
generates:
<form action="/services/6" method="post">
<input name="_method" type="hidden" value="delete" />
....
Rails uses that to call the correct controller method. Hope that helps.

edit form submitting to the wrong url and remote: true failing to be picked-up

This has been driving me nuts because it doesnt seem to make any sense.
I want to do something relatively simple.
Display an edit form in a modal on the index page.
I have the following code looping through a collection of sites
<%= render(#sites) %>
<%= will_paginate #sites %>
Within the sites partial i have the following form hidden away
<%= simple_form_for site, remote: true do |f| %>
<%= f.input :name %>
<%= f.input :matter %>
<%= f.submit "Save", :class => "button gr thirt", id: "site_save" %>
<% end %>
instead of generating the expected HTML i get the following, linking to the show action, am I missing something fundamental here?
<form accept-charset="UTF-8" action="/sites/1" class="simple_form edit_site" data-remote="true" method="post" novalidate="novalidate">
</form>
I was looping through a collection of #sites, a results returned by a call to Site.all
so the object being served to the above form is one of the |site|'s contained within #sites
If you serve a form_for form with a an object retrieved from the database or a 'new record' object like Site.new, it will automatically differentiate and modify the route etc accordingly between the create and the update action.
The site object contained in the #sites block was not recognizable by the form_for. So a quick re factor to request an edit from via ajax, and provide the form with the instance variable created by the edit action (#site = Site.find(params[:id]) ) was recognizable by the form_for helper and meant that the submit action, accordingly adjusted to the correct route.

Get data from html form to ruby in Ruby on Rails

Get data from html form to ruby in Ruby on Rails
I have some html like this
<html>
<h1>Text to PDF</h1>
<textarea name="comments" cols="40" rows="5">
Enter your Text here...
</textarea><br>
<input type="submit" value="Submit" />
</form>
</body>
</html>
I want to give the value of the text into the controller for this page/view.
How do I do this with rails?
I am new to rails, what is the mechanism for this? I don't need to write to the database just want to hand it to the controller. If there is a good tutorial for this sort of thing that would be great, I am not convince I am approaching this correctly.
You can use params['comments'] in your controller to get the value.
In your controller-
def parse_comments
comments_from_form = params['myform']['comments']
#do your stuff with comments_from_form here
end
In your view-
<h1>Text to PDF </h1>
<%= form_tag :action => 'parse_comments' do %>
<%= text_area :myform, :comments, :cols => '40', :rows => '5' %>
<%= submit_tag "Submit" %>
<% end %>
(edit: added = to form_tag opening, without it code won't work)

Resources