Rails 3, Form submitting to its controller - ruby-on-rails-3

I'm new to Rails and I've just spent another hour Googling and not finding an example.
So I have a simple form that I need to submit to an API. So I tried submitting it to the API directly but got advice that I do it in my app so I can do something with the results. Anyway, here's my simple form:
<%= form_tag(:action => 'submit') do |f| %>
<%= f.text_field :email, :value => "Your email address...", :class => "text", :id => "email", :name => 'email',
:onFocus => "change(this,'#222222'); this.value=''; this.onfocus=null;",
:size => "26" %>
<%= f.hidden_field :ref_code, :id => 'ref_code', :name => 'ref_code', :value => #referralid %>
<%= submit_tag "Enter To Win", :class => "button-positive submit" %>
<% end %>
Everything I'm seeing has forms that that use a model, I have no need to persist this data, just pass it on to the API.
So my thought was I just create an action in the home controller, where this page lives and have the action submit to it but I get a RoutingError and it's: No route matches {:action=>"submit", :controller=>"home"}
So what do I need to put in the Routes.rb? I tried:
namespace :home do
resources :submit
end
No Joy... I'm sure it's simple but I just can't find the right example.

I think that you should have a look at the ruby guides, it's very well explained (but I don't think it talks about API) and it will save you a lot of time in the future, I swear.
Not sure what you mean but I see some wired stuff, so I hope to be useful, but if you're following some tutorials from the net let us know the link.
Basically what I do is always to call an action of a controller (MVC), following this way you should have a controller (?? apis_controller ??) and call one action of it.
So you want to use form_tag instead of form_for because you're not addressing a model, therefor you want to get rid of f. and use suffix _tag (api).
<%= form_tag(send_api_path) do %>
<%= text_field_tag :email, "Your email address..." %>
<%= hidden_field_tag :ref_code, #referralid %>
<%= hidden_field_tag :api_name, 'your_api_name' %>
<%= submit_tag "Enter To Win" %>
<% end %>
Then, in your apis_controller.rb you create an action send where you send and manage your request.
#apis_controller.rb
def send
# TODO: your code here
end
Another thing is to set the routes, something like
#routes.rb
match 'apis/send' => 'apis#send', :as => :send_api
I'm sure this is not 100% working code, but it should be useful
How to call the api? I had I fast look and found this.
When you ask for help it's always good to attach the error you get, this makes it easier for people to understand the problem.

Related

Rails: No route matches [PUT] "/blog/2"

I am creating blog application in rails. I have a common form for creating and updating blog.
This is view of edit and new.html.erb
<%= render :partial => "form"%>
This is view of _form.html.erb blog:
<%= form_for #blog do |f| %>
<%= f.text_field :title, :placeholder => "Title" %><br>
<%= f.cktext_area :article, :placeholder => "Content", :ckeditor => {:toolbar => "MyToolbar"} %>
<%= f.submit %>
<% end %>
My blog is creating successfully but I am getting error on update action. This is my edit and update action in blog controller:
def edit
#blog = Blog.find_by_slug(params[:id])
end
def update
#blog = Blog.find(params[:id]) || not_found
#blog.update_attributes(params[:blog])
redirect_to "/blogs/#{#blog.slug}"
end
When I open form from edit view, and click on update button, it throws error:
No route matches [PUT] "/blog/2"
My routes.rb is:
resources :blogs
get 'blog', to: 'blogs#index'
get '/blog/:id', to: 'blogs#show', as: 'blog'
I am not getting where it is going wrong. I tried to add "url: blogs_path" in form_for, it removes the error but doesn't save the edit changes.
Can anybody help me where I am going wrong here?
Thank you.
Okay. I dont understand why you want to go against conventions. Anyway, using form_for resource would automatically generate action URL as a PUT to /resources/:id if its an update operation.
So to override this you need to do two things.
update your routes to support this:
Add this line to your routes file:
put 'blog/:id' => 'blogs#update', :as => 'update_blog'
It is important that you put this line above your 'resources :blogs` call.
2 . specify the URL to which the form should submit:
You will need to create the form tag like this:
<%= form_for #blog, :url => update_blog_path(#blog) do |f| %>
Try this and let us know.

Validations on tableless form fields in rails 3

I am attempting to run a form destined for the app's home page, which uses simultaneously tableless and database-stored variables. I need to run validations on the form. I need to run validations, one in particular which compares two of the tableless values.
My eventual goal is to get the validations running client-side via the following gem:
https://github.com/bcardarella/client_side_validations
Initially though, I want to get the validations working upon form submission.
A first question that arises is which model should hold the mail validation logic. The homePage has to do many things, is not a model and, above all, the search results lead to a different controller.
Subsequently, although some validations are one-off and don't really need to be factored out, I would place the validation logic in app/validators/different_objects_validator.rb
class DifferentObjectsValidator < ActiveModel::Validator
def different_objects
errors.add(:different_objects, "cannot be less than quantity") unless
self.quantity >= self.different_objects
end
end
Form data is:
<%= form_tag result_quote_request_path, :method => :get do %>
Base <%= number_field :quote, :base, :size => 5 %>
Height <%= number_field :quote, :height, :size => 5 %>
Quantity <%= number_field :quote, :quantity, :size => 5, :value => 1 %>
Different source objects <%= number_field :quote, :different_objects, :size => 5, :value => 1 %>
<%= submit_tag "find", :name => nil %>
<% end -%>
Then
class Quote < ActiveRecord::Base
include ActiveModel::Validations
validates :different_objects, different_objects_valid => true
After restarting Thin web server, this results in:
ActionView::Template::Error (undefined method `name' for nil:NilClass):
But this is a bit of a red herring: without the validation, the form generates a search result
I realize many things may be wrong here. I am having trouble getting the proper focus of where the validations are invoked combined with tableless states.
Your error comes from the following:
<%= submit_tag "find", :name => nil %>
Simply do
<%= submit_tag "find" %>

Add message to formtastic semantic error block

If there are semantic errors in the form (mostly from external API), I'd like to add an explanatory message, like so:
<%= semantic_form_for #order, :url => checkout_purchase_url, :html => {:class => 'payment'}, :wrapper_html => { :class => "field" } do |f| %>
<% if f.has_errors? %>
<p>There were errors that prevented your order from being submitted. If you need assistance, please contact us toll-free at <strong>1-800-555-5555</strong>.</p>
<%= f.semantic_errors %>
<% end %>
<% end %>
However, has_errors? is a protected method. Is there a way that I can do this? Thanks.
If you have nested attributes you won't see any errors associated with them. To ensure you get all base errors and any nested attributes errors. Make sure your model contains:
validates_presence_of :nested_object
validates_associated :nested_object
and in your form:
f.semantic_errors *f.object.errors.keys
Not as hard as I thought. I fixed it by checking for errors on the object instead of the form:
<% if #object.errors.any? %>
<p>There were errors that prevented your order from being submitted. If you need assistance, please contact us toll-free at <strong>1-800-555-5555</strong>.</p>
<%= f.semantic_errors %>
<% end %>
Thanks for those who viewed.
For completeness, here's an alternative approach if you want to show similarly helpful messages on each field:
= f.label :title
- if f.object.errors.any?
.error = f.object.errors[:title].flatten.join(' and ')
= f.text_field :title
This gives a nicely formatted and easily-styled list of errors for each field. (You can use semantic_errors instead of object.errors if you prefer, same result.)

Why is my nested text_area helper adding html tags?

I have a text_area in a partial in a complex form that is called like so
<%= f.fields_for :notes do |notes_form| %>
<%= render :partial => 'note', :locals => {:f => notes_form, :operation => f, :count => operation.notes.count} %>
<% end %>
<p><%= add_child_link "Add note", :operation_notes %></p>
and the partial looks like this
<% count ||= 2 %>
<div class='fields'>
<%= f.text_area :note_text, :rows => "4", :class => "notes" %>
<%= remove_child_link "x", f, count %>
</div>
There can be many notes on the form hence the add and remove child links.
The issue I'm having is that if I add a note with the text 'abcd', when I bring up the edit form I get '<p>abcd</p>'. If there are line breaks in the note it adds <br /> tags. The text_area form helper seems to be using the simple_format helper but I have no idea why. Can anyone help as this is very undesirable behaviour?
Ah solved,
Earlier on the same page I was displaying the note and using simple_format to format it with
<%= simple_format note.note_text %>
It seems that simple_format is somewhat destructive as after this, a call to note.note_text always returns the formatted text. If I change the above to
<%= simple_format note.note_text.dup %>
then the note_text attribute is not altered and I get the appropriate results.
I will have to look more closely at simple_format but this really strikes me as undesirable behaviour.
EDIT
It looks like this has been corrected in Rails 3.1
I would suspect that you have something in your Note model that is processing the text. Check for callbacks in this model.

Routing error while using partial form in rails 3

does anyone know how to use a form partial to create and update data about an object? My update method seems to work, but I can't create a new object. Every time I clink on the 'Add new ad' I get this error:[ActionController:Routing Error in Classified#new No route matches {:controller=>classified}]. Here is the code for the partial form: The error points to the first line:
<%= form_for(#classified) do |f| %>
<p>
<%= f.label :title %><br/>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :price %><br/>
<%= f.text_field :price %>
</p>
<p>
<%= f.label :location %><br/>
<%= f.text_field :location %>
</p>
<%= f.label :description %><br/>
<%= f.text_area :description %>
<%= f.label :email %><br/>
<%= f.text_field :email %>
<%= f.submit %>
<% end %>
<%= link_to 'Back', {:action => 'list'} %>
Here are my methods for new, edit and update in the Classified controller class:
def new
#classified=Classified.new
end
Here is the 'def create' method:
def create
#classified = Classified.new(params[:classified])
if #classified.save
redirect_to :action => 'list'
else
render :action => 'new'
end
end
I suspect the problem is in my config/routes.rb. I already have this line:
resources :classified
I have also put:
root :to => "Classified#list"
root :to => "Classified#new"
root :to => "Classified#show"
root :to => "Classified#edit"
root :to => "Classified#form
Could the problem be with the routes.rb file. And how comes it works with the update method and not the new method? Please help. I have tried all possible tricks to no avail. I will be so glad. Thanks in advance
I would like to know the result of your rake routes, because you use the singular for your controller classified.
Could it be classifieds, with the S in all your routes? I'm not that sure because resources: classified I guess came from the scaffold and so it should be good, then you miss a `"' on your last line but this could be a typo.
I would recommend having a plural name for the resource, as that is the norm for most resources:
resources :classifieds
You will also need to change your controller name and class name to classifieds_controller and ClassifiedsController
Also, your named routes should be lowercase (although you should get rid of these routes altogether):
root :to => "classifieds#list"
Get rid of the root routes. The resources line will create all the routes you need. And you are only supposed to have one root route in routes.rb and that should point to your home page controller#action.
If you have an action for form, then you don't need that either.. just mentioning this because you created a route for "Classified#form". Controller actions are not necessary for partials.
Your new and create methods and the form look ok at first glance. Try reworking your routes first and if you are still having problems, run rake routes from the command line and post the output in your question and leave me a comment on this answer and I will see if I can help you figure it out.
Read this first:
http://guides.rubyonrails.org/routing.html