How to submit a form from any controller - Rails? - ruby-on-rails

I want to put a simple email signup form in the footer of every page of my website. So I created a subscription scaffold and have made the following partial:
<%= form_for #subscription, :url => {:controller => 'subscriptions', :action => 'create'} do |f| %>
<div class="input-append">
<%= f.text_field(:email, :id => "appendedInputButton", :placeholder => 'Subscribe', :class => 'span4') %><button class="btn" type="submit" name="commit">Subscribe</button>
</div>
<% end %>
But despite specifying the controller and action I'm getting the following error:
undefined method `model_name' for NilClass:Class
The form works fine from the subscriptions/new page but how do I make it so I can submit the form from any controller and any page without having to define #subscription everywhere?

The simplest thing would be to simply change:
<%= form_for #subscription ...
To:
<%= form_for Subscription.new ...
And, like has already been noted, I doubt you need the url options.

Related

Rails form_for sending params to controller action and not model

In the controller review_queue I have a custom action that posts a result to a target URL, I want to build a form for this action. I am not going to save any of the fields to the DB I am just going to pass them in the params to the post_review action.
def post_review
RestClient::Request.execute(:method => :post,
:url => Rails.application.secrets['target_url'],
:content_type => :json,
:payload => #result_params.merge!(params[:reasons]).to_json,
:headers => HEADERS)
end
In the view I have a form that will be filled out and on submit it should send up the reasons when the form is submited, I am setting the review_queue_id and the status in the form, since these are static, but the reasons should come from the textarea
<%= form_for(:review_queue, url: { action: 'post_review', :review_queue_id => #review_queue.id, :status => 'accepted'} ) do |f| %>
<div class='form-group'>
<label for='comment'>Please give a reason? (required)</label>
<%= f.text_area(:reasons, placeholder: 'Your commentns ...', rows: 9, class: 'form-control') %>
</div>
<div class='modal-footer'>
<%= f.submit 'Approve', class: 'btn btn-success btn-decission btn-modal-left-side' %>
<button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
</div>
<% end %>
error message:
NoMethodError - undefined method `reasons' for #<ReviewQueueApplication:0x007fa7ff7832d8>:
It seems as if rails is assuming the MVC architecture here, and assuming I want to pass the reasons to the review_queue model. there is no reasons column so it's dropping a no method error. Is there a way of specifying that the form is 'temporary' and only getting as far as the controller?
This seems like it should be a simple thing but there is some rails magic happening here.
NoMethodError - undefined method `reasons' for
ReviewQueueApplication:0x007fa7ff7832d8
form_for assumes that you are creating a form for a model object and expects the fields to be present in that specific model's table(in a normal situation).
You should be going with form_tag
<%= form_tag post_review_path, method: :get, :review_queue_id => #review_queue.id, :status => 'accepted'} ) do |f| %>
<div class='form-group'>
<label for='comment'>Please give a reason? (required)</label>
<%= text_area_tag(:reasons, placeholder: 'Your commentns ...', rows: 9, class: 'form-control') %>
</div>
<div class='modal-footer'>
<%= submit_tag 'Approve', class: 'btn btn-success btn-decission btn-modal-left-side' %>
<button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
</div>
<% end %>
And in the controller access it like params[:reasons]. Also if you noticed, I've added method: :get to the form_tag as you don't want to save the info to DB
The rails helper form_for is used for forms for rails resources. You want to use the form_tag helper. Search for form_for and form_tag here for more information on these 2 methods.

Rails simple form routing issue

I have a form in Rails
<div class="page-header">
<h3>Create Blah</h3>
</div>
<%= simple_form_for #blah do |f| %>
<%= f.input :id %>
<%= f.input :name %>
<%= f.input :pho %>
<%= f.input :fun %>
<%= f.submit :class => 'btn btn-primary' %>
<% end %>
<br>
When I click the submit button, where does the code attempt to go? Does it call the create method for blah_controller.rb? Because currently, I get a routing error
Routing Error
uninitialized constant BlahsController
Here is the BlahController#create method:
def create
authorize! :create, :blahs
#blah = Blah.new(params[:blah])
if #blah.save
redirect_to admin_blah_path(#blah), :notice => 'New blah created!'
else
render :new
end
end
In my rake routes, I have
admin_blahs GET /admin/blahs(.:format) admin/blahs#index
POST /admin/blahs(.:format) admin/blahs#create
new_admin_blah GET /admin/blahs/new(.:format) admin/blahs#new
edit_admin_blah GET /admin/blahs/:id/edit(.:format) admin/blahs#edit
admin_blah GET /admin/blahs/:id(.:format) admin/blahs#show
PUT /admin/blahs/:id(.:format) admin/blahs#update
DELETE /admin/blahs/:id(.:format) admin/blahs#destroy
It looks like your BlahsController is a namespaced controller, living under the Admin module (i.e., its fully-qualified name is Admin::BlahsController). If so, when constructing forms you must also provide the :admin namespace, using something like the following:
<%= simple_form_for [:admin, #blah] do |f| %>
See the Rails Guide to Form Helpers, under the "Dealing with Namespaces" section.

Editing a single form field with rails

I have a form field in a view that is separate from my initial form. I want the person using the application to be able to edit a single field without having to pull up the entire form. My code is as follows
<%= form_for :user, :url => {:controller => 'users', :action => 'update' } do |f| %>
<%= f.text_field :barcode %>
<%= submit_tag 'Register' %>
<% end %>
When trying to submit the changes to the specified form field I receive an error on the create method I believe. It redirects me to the user controller with the proper id but gives me the following error.
Unknown action
The action '1' could not be found for UsersController
I have tried changing the method from update to create, but then it brings up the blank form, I just want to be able to edit the specified field without having to re-create the form and get the error. Any ideas?
You are not passing the user object to the form.
Try also using the path helper generated by the routes:
<%= form_for #user, :url => user_path(#user) do |f| %>
<%= form_for(#user), :url => url_for(:controller => 'users', :action => 'update') do |f| %>
<%= f.text_field :barcode %>
<%= f.submit, 'Register' %>
<% end %>
It should work now...

Rails: Change form action from submit_tag

I have a form which is always submitting the form to the "update" function in the controller, and I have created this form using "remote_form_for" tag. In this form I have objects from different tables, and from this form I want to submit entire form data to another function(not to the "update" function) via AJAX request.
I have tried many methods including using submit tag with action
<% remote_form_for #employee, :url => organization_employee_path(#organization, #employee), :method => :put do |employee_form| %>
// form objects and other functionalities
....
....
// views inside the forms
<div id="employee_header_div">
<%= render :partial => "employee_header", :locals => {:employee => #employee} %>
</div>
...
...
<%= submit_tag "page_level_validation", :id => "page_level_validation" , :action=>"validate"%>
<% end %>
But the Ajax request always calling the same "update" function.
It would be very helpful, if anyone helps to resolve this issue.
You can't set the submit to point to a different place than the main form has specified (unless you want to use the HTML5 formaction attribute and deal with the browser compatibility consequences).
However, what you could do is create a new action in your controller which deals with the situation.
e.g..
<% remote_form_for #employee, :url => organization_employee_validate_path(#organization, #employee), :method => :put do |employee_form| %>
in your controller
def validate
#do something loosely based around the update method
end
not forgetting to add the appropriate routes.
Try this:
<% form_for #employee, :remote => true, :url => organization_employee_path(#organization, #employee), :method => :put do |employee_form| %>

rails admin edit view path routes

I've got an admin section setup, but am having trouble getting the "update" route to work.
Getting error when hitting "update" via the edit view:
"No action responded to 2."
For some reason the route is responding to the :id as the :action.
Parameters:
Parameters: {"commit"=>"Update", "action"=>"2", "_method"=>"put", "admin"=>{"ended_at(1i)"=>"2010", "ended_at(2i)"=>"8", "ended_at(3i)"=>"22"}, "id"=>"edit", "controller"=>"admin/subscriptions"}
The edit view uri:
/admin/subscriptions/2/edit
Edit view:
<% form_for :admin, #subscription, :html => {:method => :put} do |f| %>
<p>
<%= f.label :ended_at %><br />
<%= f.date_select :ended_at %>
</p>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
Route:
map.namespace :admin do |admin|
admin.resources :subscriptions
end
I assume I need to do something differently in the form_for method or maybe the routes, but everything I've tried isn't working.
Thanks for the help!!
It should be this:
<% form_for [:admin, #subscription] do |f| %>
By putting :admin and #subscription in square-brackets, this makes it into an array which is passed as the first argument to form_for. The benefit of this is if #subscription is a pre-existing record (as-in, one found by find, not created with new) then Rails will know to set the form method to PUT.
This works:
<% form_for :admin, #subscription, :html => {:method => :put}, :url => { :action => "update" } do |f| %>
Seems verbose though. Any better ideas?
Try
- form_for :subscription, #subscription do |f|
We're using formtastic here.

Resources