i'm new to ruby on rails and I keep getting this error when trying to update an object.
here's my controller:
class SetorController < ApplicationController
def index
#setor = Setor.all
end
def new
end
def show
#setor = Setor.find(params[:id])
end
def create
#setor = Setor.new(setor_params)
#setor.save
redirect_to #setor
end
def edit
#setor = Setor.find(params[:id])
end
def update
#setor = Setor.find(params[:id])
if (#setor.update(setor_params))
redirect_to #post
else
render 'edit'
end
end
private def setor_params
params.require(:setor).permit(:nome, :sigla, :cnpj)
end
end
this is the index page - where I link to edit the object:
<%= #setor.each do |s| %>
<%= s.nome %> |
<%= s.sigla %> |
<%= s.cnpj %> |
<%= link_to "edit", edit_setor_path(s.id) %> <br>
<% end %>
and this is the update form:
<h1> Editar Setor </h1>
<%= form_for :setor, url: setor_path(:update) do |f| %>
<p>
<%= f.label :nome %>
<%= f.text_field :nome %> <br>
<%= f.label :sigla %>
<%= f.text_field :sigla %> <br>
<%= f.label :cnpj %>
<%= f.text_field :cnpj %> <br>
</p>
<%= f.submit %>
<% end %>
what am I missing?
Thanks!
First, make sure you have a route that matches edit_setor_path. You can do this by running rails routes in your terminal or by going to the url localhost:3000/rails/info/routes in your browser.
On your index page, you have the following:
<%= link_to "edit", edit_setor_path(s.id) %> <br>
You do not need to pass in the id of the s object. Rails will figure this out on its own. Instead, just pass in the object:
<%= link_to "edit", edit_setor_path(s) %> <br>
Change #setor in the index action of your SetorController to #setors and change #setor in your index.html.erb file to #setors.
Change the :sector in your edit.html.erb to #setor. You can also remove url: setor_path(:update) from the edit.html.erb form.
These changes follow Rails conventions. You should try to follow Rails conventions as much as possible, especially when just learning Rails.
Try to mention #setor object in the form code:
<%= form_for #setor do |f| %>
How about trying something like this:
Rename your controller to setors_controller.rb and change the class name to SetorsController -- this is to follow the typical Rails naming convention.
Then make sure you have a route:
# config/routes.rb
Rails.application.routes.draw do
resources :setors
end
Update your view's form_for tag to use the instance variable set up in the controller:
# app/views/setors/edit.html.erb
# NOTE: folder path above... "setor" is now "setors" to follow the Rails convention
<%= form_for #setor do |f| %>
<p>
<%= f.label :nome %>
<%= f.text_field :nome %> <br>
<%= f.label :sigla %>
<%= f.text_field :sigla %> <br>
<%= f.label :cnpj %>
<%= f.text_field :cnpj %> <br>
</p>
<%= f.submit %>
<% end %>
Related
I am trying to save parent as well as child object at the same time using accepts_nested_attributes_for
Code in controller's new method:
def new
#project = Project.new
#project.instances.build
end
and form looks like this:
<%= simple_form_for(#project) do |f| %>
<%= f.input :name %>
<%= link_to "Add New Instance", new_project_instance_path(#project), id: "new_link", remote: true %>
<% end %>
The route entry for this is:
resources :projects do
resources :instances
end
And the fields that need to be displayed instances/_form.html.erb:
<%= form.simple_fields_for :instances do |i| %>
<%= i.input :user_id %>
<%= i.input :password %>
<%= i.input :service_url %>
<% end %>
The issue here project_id being :nil, it is giving error:
No route matches {:action=>"new", :controller=>"instances", :project_id=>nil} missing required keys: [:project_id]
I need to somehow call <%= render 'cdd_instances/form', form: f %>, so that the fields get rendered below the Project details, how should I implement this?
I think your #project is null you have to pass like:
new_project_instance_path(project_id: (#project || ''))
In this case you are not able to pass non-persisted #project to create this link_to url.
I believe you are looking for something like: cocoon.
<%= simple_form_for #project do |f| %>
<%= f.input :name %>
<h3>Instances</h3>
<div id="instances">
<%= f.simple_fields_for :instances do |instance| %>
<%= render 'instance_fields', f: instance %>
<% end %>
<div class="links">
<%= link_to_add_association 'add instance', f, :instances %>
</div>
</div>
<%= f.submit %>
<% end %>
Cheers!
New and Create are working good, data is stored in the database but edit and update is having issues.
This is my sages controller sages_controller.rb
class SagesController < ApplicationController
def home
end
def about
end
def new
#sage = Sage.new
end
def create
#sage= Sage.new(sage_params)
if #sage.save
flash[:success] = 'Thanks for Joining'
redirect_to '/thanks'
else
flash[:notice] = 'Please fill the form Correctly'
render 'new'
end
end
def edit
#sage=Sage.find(params[:id])
end
def update
#sage = Sage.find(params[:sage])
if #sage.update_attributes(sage_params)
redirect_to '/thankss'
else
render 'new'
end
end
def resources
end
private
def sage_params
params.require(:sage).permit(:Name, :Email, :Address, :Number)
end
end
THis is my view for new method new.html.erb
<div class="contact" style="padding: 50px; color: orange ">
<%= form_for #sage do |f| %>
<div class="form-group" >
<h3><%= f.label :Name%></h3>
<%= f.text_field :Name %>
<br/>
</div>
<div class="form-group" >
<h3><%= f.label :Email%></h3>
<%= f.email_field :Email %>
</div>
<div class="form-group" >
<h3><%= f.label :Address%></h3>
<%= f.text_field :Address %>
<br/>
</div>
<div class="form-group" >
<h3> <%= f.label :Number%></h3>
<%= f.number_field :Number %>
<br/>
</div>
<br/>
<br/>
<div class="submit" >
<h2><%= f.submit 'SUBMIT'%></h2>
</div>
<% end %>
<%= link_to 'Edit', 'edit' %>
</div>
`
This is my view for Edit method edit.html.erb
<%= form_for #sage do |f| %>
<%= f.label :Name %>
<%= f.text_field :Name %>
<br/>
<%= f.label :Email %>
<%= f.text_field :Email %>
<br/>
<%= f.label :Address %>
<%= f.text_field :Address %>
<br/>
<%= f.label :Number %>
<%= f.text_field :Number %>
<br/>
<%= f.submit 'Update' %>
<% end %>
`
This is my routes in routes.rb
resources :sages,only: [:new,:create,:edit, :update]
get 'sages/home'=>'sages#home'
get 'sages/about'=>'sages#about'
get 'sages/resources'=>'sages#resources' `
You are doing it wrong, how can you edit a record if it doesn't exist. In new.html.erb you have added a link
<%= link_to 'Edit', 'edit' %>
Remove that line, its wrong. You can only edit an existing record and not a new record. Also, the route is wrong. It should look something like
<%= link_to 'Edit', edit_sage_path(#sage) %>
Hope this helped!
Which URL or path you are using? I imagine you are using an incorrect URL or path.
With the routes you mentioned you should have the following access route for edit:
edit_sage GET /sages/:id/edit(.:format) sages#edit
So either you use edit_sage(id) or you type in the URL with /sages/id/edit. Please note that you have to replace id (in path or URL) by a valid id of a sage.
In the new view you cannot edit an object that does not exist (i.e. is not persisted in database).
<%= link_to 'Edit', 'edit' %>
is wrong as mentioned by other users.
Also if ever you want to call edit, consider what I mentioned in the beginning. Make sure you pass a valid id or sage object that effectively exists in database.
First thing you need to change edit link, it should be like :
<%= link_to 'Edit', edit_sage_path(#sage) %>
Second thing you can't call edit link in your new template because in this case you have #sage is empty (it just initiated),you can edit your sage by adding 'Edit' link to either index or show template
in update action change
def update
#sage = Sage.find(params[:id])
if #sage.update_attributes(sage_params)
redirect to ('/thanks')
else
render 'new'
end
end
Like an example if you have record with id = 2 then write url like /sages/2/edit and you will get data with record id=2.
Do this below change in your update method also,
#sage = Sage.find_by_id(params[:id])
The link i gave was wrong for edit in new.html.erb, removed it
and changed the route of edit to:
get 'sages/id/edit'=>'sages#edit' in routes.rb and now it works fine....
I made a simple demo site, with an model for the patients name (name:string) and another model with the treatment (content:text). I created this "project" to learn more about the accepts_nested_attribute for tag and the fields_for tag.
Now my problem is that on the patient show page i created an nested formula for the treatment , like you can see here:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #patient.name %>
</p>
<ol>
<% for treatment in #patient.treatments %>
<li><%= treatment.content %></li>
<% end %>
</ol>
<%= form_for(#patient) do |f| %>
<%= f.fields_for :treatments do |builder| %>
<div class="field">
<%= builder.label :content %><br />
<%= builder.text_field :content %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit', edit_patient_path(#patient) %> |
<%= link_to 'Back', patients_path %>
So my problem is that in the builder.text_field :content better called the input shows up the last saved treatment from <%= builder.content %>, but i want that he does not update it instead i want to add new treatments! Hopefully somebody understands me! Thanks
I would create separate controller for creating only the treatment, eg.
# treatments_controller.rb
class TreatmentsController < ApplicationController
def create
#patient = Patient.find(params[:patient_id])
#treatment = #patient.treatments.new(params[:treatment])
if #treatment.save
redirect_to #patient
else
# handle unsuccessful treatment save
end
end
end
# routes.rb:
resources :patients do
resources :treatments, only: :create
end
# form:
<%= form_for #patient, #treatment do |f| %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should also set #treatment variable in the patient#show action, like this:
#treatment = #patient.treatments.new
I have following code in my edit view:
<%= form_for #content do |f|%>
<% if f.text_field :home %>
<%= f.label :Home %>
<%= f.text_field :home %>
<% elsif f.text_field :aboutus %>
<%= f.label :Abouts %>
<%= f.text_field :aboutus %>
<% end %>
<%= f.submit%>
Here #content contain following information:
id: "1", home: "staticcontent", aboutus: "staticcontent"
so i wants that if someone wants to edit home page he can see only home submission form and if he choose aboutus, he can see edit form page for only about us.suggest me whats correct way to use if,else in this block?
You could pass a URL param and work with that. For example:
# in some view
<%= link_to "Edit Homepage", edit_content_path(page: "home")
# this will link to /contents/:id/edit?page=home
Then in your form:
<%= form_for #content do |f|%>
<% if params[:page] == "home" %>
<%= f.label :home %>
<%= f.text_field :home %>
<% else %>
<%= f.label :about_us %>
<%= f.text_field :about_us %>
<% end %>
<%= f.submit%>
Notice I downcased the labels, and changed aboutus to about_us so that the label displays correctly.
I'm using basic scaffold structure. What I need, is to add 'moderate' action and view by changing published to true. In my idea, on moderate.html I should get the list of all unpublished entries with the ability to change and save their parameters.
Here are parts of my code:
#names_controller.rb
def moderate
#name = Name.find(:all, :conditions => {:published => false} )
respond_to do |format|
format.html
format.xml
end
end
#moderate.html.erb
<% form_for #name.each do |f| %>
<%= f.error_messages %>
<%= f.text_field :which %>
<%= f.text_field :what %>
<%= f.check_box :published %>
<%= f.submit %>
</p>
<% end %>
Instead I'm getting this error:
NoMethodError in Names#moderate
Showing app/views/names/moderate.html.erb where line #1 raised:
undefined method `enumerable_enumerator_path' for #<ActionView::Base:0x1042c3e90>
Extracted source (around line #1)
So, can you help to newbie please?
ruby 1.8.7 (2009-06-12 patchlevel 174)
[universal-darwin10.0] Rails 2.3.5
If you want to update each name in a separate form, then all you need to do is move the loop above form_for:
<% #name.each do |n| %>
<% form_for n do |f| %>
<%= f.error_messages %>
<%= f.text_field :which %>
<%= f.text_field :what %>
<%= f.check_box :published %>
<%= f.submit %>
</p>
<% end %>
<% end %>
But if you'd like to do it all in one submit (a single form) then I guess you can't use form_for. I'd use form_tag to create a custom form to update multiple instances. This should work both for create and edit form:
<%= form_tag moderate_names_path do %>
<% #names.each do |name| %>
<fieldset>
<%= fields_for "name[#{name.id}]", name do |name_fields| %>
<p><%=name_fields.label(:this)%>: <br /><%= name_fields.text_field :this %></p>
<p><%=name_fields.label(:that)%>: <br /><%= name_fields.text_field :that %></p>
<p><%= name_fields.check_box :published %> <%=name_fields.label(:published)%></p>
<% end %>
</fieldset>
<br />
<% end %>
<%= submit_tag %>
<% end %>
NOTICE: I changed #name to #names in the second example