When updating an object, we should :method => :put to override the post in the form as the following:
<%= simple_form_for #task, :url => update_task_url, :method => :put do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name %>
<%= f.input :description %>
</div>
<div class="form-actions">
<%= f.submit 'Update Task'%>
</div>
<% end %>
<%= link_to 'Back', tasks_path %>
In the controller before making the request, I tried to render the params to check everything is correct as follow:
render text: tasks_params
uri = URI.parse("http://localhost/tasks/public/api/tasks/"+params[:id])
response = Net::HTTP.post_form(uri, task_params)
render text: response.body
but I get the following without the _method attribute:
{"name"=>"Task#1", "description"=>"lorem ipsum"}
and as a result the request is not successful on the server side.
What am I missing here exactly?
You should post to the desired controller action like so
<%= simple_form_for #task, :url => update_task_url, :method => :post do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :name %>
<%= f.input :description %>
</div>
<div class="form-actions">
<%= f.submit 'Update Task'%>
</div>
<% end %>
I would add a debugger break point in the update action in your TasksController just to make sure you are hitting the right route.
Related
I have a form_tag in my edit view:
<%= form_tag stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do %>
<div class="form-group">
<%= label_tag 'csv_batch_file', 'Select batch file' %>
<%= file_field_tag 'csv_batch_file', class: 'form-control' %>
</div>
<br>
<div class="form-group">
<%= label_tag 'potential_item_id', 'Input item id' %>
<%= text_field_tag "potential_item_id" %>
</div>
<br>
<%= button_tag 'Stage', class: 'btn btn-primary' %>
<% end %>
Currently it puts to stage_batches/:id which is what I want.
However, I want to add another button that posts to some other controller, say Foo#create. I read in another answer that the formaction option will work. But the given example uses form_for and not form_tag:
<% form_for(something) do |f| %>
...
<%= f.submit "Create" %>
<%= f.submit "Special Action", formaction: special_action_path %>
<% end %>
How do I rewrite my form_tag as a form_for?
<%= form_tag stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do %>
==>
<%= form_for #stage_batch, url: stage_batch_path(#stage_batch), multipart: true, class: 'form-inline', role: 'form', method: :put do |f|%>
Also the same as:
<%= form_for #stage_batch, class: 'form-inline' do |f|%> #if #stage_batch is new_record? then method: :post, else method: :put
PS: You should try this https://github.com/plataformatec/simple_form, a lifesaver.
With simple_form your form can be transformed to:
<%= simple_form_for #stage_batch do |f|%>
<%= f.input :csv_batch_file, as: :file %>
<%= f.input :potential_item_id %>
<%= f.submit 'stage' %>
<%end%>
simple and beautiful.
I am new to ruby on rails and got an error while following http://guides.rubyonrails.org/getting_started.html tutorial.the error come at when i am updating the form like this "<%= form_for :post, URL :posts_path do |f| %>"..When i move my cursor to that error it says Unexpected tSYMBEG..i just followed the instructions...The error occur on 2nd line .any help will be appreciable
<h1>New Post</h1>
<%= form_for :post, url :posts_path do |f| %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br />
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= form_for #post do |f| %> will do. Otherwise, try this: <%= form_for :post, url: :posts_path do |f| %>
There is a typo in your code. It causes the issue.
replace
url :posts_path
with
url: posts_path
You can also use.
<%= form_for :post, :url => posts_path do |f| %>
or
<%= form_for #post do |f| %>
All are same..
I am using OpenStruct form for in my view like the following,
<%= form_for(OpenStruct.new(params[:f]), as: :f, url: product_types_path, method: :get, remote: true, html: {class: 'type'}) do |f| %>
<div class="field">
<%= f.label :product_type_id %>
<%= foreign_key(f, :product_type_id, Asset::Product::Type) %>
</div>
<% end %>
I want to hide the other form elements if product_type_id is nil or blank or empty?
I tried this,
<% unless product_type_id.blank? %>
<div class="field">
<%= render 'form' %>
</div>
<% else %>
<p>Select Product Type</p>
<% end %>
So if I got it right what you want to do is not to render the form if what you received with the param product_type_id is blank.
Is it possible for you to instatiate the variable in the controller instead of defining it directly in the form builder?
For instance in your controller:
def index
#product_type = OpenStruct.new(params[:f])
end
and in your view:
<% unless #product_type.product_type_id.blank? %>
<div class="field">
<%= render 'form', product_type: #product_type %>
</div>
<% else %>
<p>Select Product Type</p>
<% end %>
and finally your partial:
<%= form_for(product_type), as: :f, url: product_types_path, method: :get, remote: true, html: {class: 'type'}) do |f| %>
<div class="field">
<%= f.label :product_type_id %>
<%= foreign_key(f, :product_type_id, Asset::Product::Type) %>
</div>
<% end %>
This is probably simple, I'm still coming to terms with rails syntax. What is the right syntax to pass the address_id in the url for form_for to a modified route?
This is the form - note the "address_id parameter"
<div class="one_fourth floatcenter">
<%= form_for address, :url => edit_address_path(:id => address.id), :method => :get do |f| %>
<%= content_tag(:button, :class => 'btn btn-inverse') do %> Edit Address
<% end %>
<% end %>
</div>
And this is the route I've configured:
get "edit_address/:id" => "member/addresses#edit"
Id is not being passed to the controller for some reason...
form_for address should be enough if address is a persisted object, but if it's not enough, then form_for address, url: edit_address_path(address) is what you want.
This is very simple. In place of url, you put your post method route:
<%= form_for(#post, url: super_posts_path) do |f| %>
...
<% end %>
You also call by action
<%= form_for #friend,:url=> { action: "create_friend"} do |f|%><br>
<%= f.label :u_from %>
<%= f.text_field :u_from %>
<%= f.label :u_to %>
<%= f.text_field :u_to %>
<%= f.submit%>
<% end %>
In my app I have User, Post and Comment models.
When a User wants to comment on Post the new action from the Comments controller takes over. The Post (to be commented on) is shown and the User enters his Comment.
However, when the User submits, I want to pass the Post.id and the Comments.content to the create action. How do I do that?
Here is the comments/new.html.erb
<%= form_for #comment do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.text_area :comment %>
</div>
<div class="actions">
<%= f.submit "Done" %>
</div>
<% end %>
Thanks to all of you. I did the nested routing and my new.html.erb now has
<%= form_for [#post,#comment] do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<% f.hidden_field :post %>
<div class="field">
<%= f.text_area :comment %>
</div>
<div class="actions">
<%= f.submit "Done" %>
</div>
<% end %>
However I get: undefined method `comment' and I cant figure that bugger out.
My guess is that each Comment must belong to a Post If that's the case then this seems like the perfect candidate for nested routes. http://guides.rubyonrails.org/routing.html#nested-resources
resources :posts do
resources :comments
end
So in your case both the post id and the comment id would be part of the URL:
# Will submit to a URL like /posts/1/comments
# or /posts/1/comments/1
<%= form_for [#post,#comment] do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.text_area :comment %>
</div>
<div class="actions">
<%= f.submit "Done" %>
</div>
<% end %>
You would need to handle the post_id in your comments controller actions.
First of all you have to pass Post.id to the comments new action. Something like
link_to "Add comment", new_comment_path( params[ :id ] )
I assume that you're following conventions so params[ :id ] is Post.id. Later in your Comment#create instantiate new comment with
#comment = Comment.new( :post_id => params[ :id ] )
which will create comment related to the post. Finally form for new comment
<%= form_for #comment do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<%= f.hidden_field :post_id %>
<div class="field">
<%= f.text_area :comment %>
</div>
<div class="actions">
<%= f.submit "Done" %>
</div>
<% end %>
In the view (using HAML)
=form_for( #comment, :as => :comment) do |f|
=f.hidden_field :post_id
=f.hidden_field :user_id
=f.text_area :comment
=f.submit "Submit"
and in the Comment#new controller:
#comment = Comment.new(:user_id => #user.id, :post_id => #post.id)