Same form for Edit and New methods - ruby-on-rails

I want to use same html form for Edit and New methods.
Controller methods:
def new
render "edit"
end
def edit
if params[:id].present?
#goat = Goat.find(params[:id])
else
#goat = Goat.new
end
end
Edit form:
<% form_for #goat do |f| %>
<%= f.text_field :title %>
<%= f.submit "Update" %>
<% end %>
It works well for Edit method when #goat record exists, but for New method, when controller gives #goat = Goat.new I got an error:
undefined method model_name for NilClass:Class
How to fix this?

The problem is that you're not actually setting the new #goat for your html.
In this code:
def new
render "edit"
end
This doesn't call the edit method on your controller; instead it goes straight to the view layer to render the edit.html.erb file. So there's no value for #goat set, and thus the error you get.
Better is code like what #user2191327 provided. You should also look at what the scaffold would generate for your controller; it's a good guide to what idiomatic Rails looks like.

if you only want to use the same html just use render :template
def new
#goat = Goat.new
render template: 'edit'
end
def edit
#goat = Goat.find(params[:id])
end
or better way: use render partial in templates edit.html && new.html
P.S. using action 'edit' instead 'new' not a good idea, so if you look in your routes.txt file, you will see that path to action includes :id of class instance.

Related

How to access related models in RoR after using link_to?

I use wkhtmltopdf to convert a page to pdf
<%= link_to "download" user_group_assessments_path(#user, #group, #assessment, format: 'pdf') =>
It will go to my AssessmentsController and call my index method, it looks like:
#assessments = Assessment.all
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
end
In show.pdf.erb I access user, group and assessment.
Every thing is ok and it works without any problem. But when I call
<% #assessment.measurements.each do |m| %>
...
<% end %>
I get the following error:
Undefined method 'measurements' for nil:NilClass
And it points to the line where I am trying to access measurement.
How can I access the model 'measurement' from this file?
You need to send your assessment details to your view. for example:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
locals: {:assessment => #assesment}
end
end
Then in your view assessment can be accessed as
<% assessment.measurements.each do |m| %>
...
<% end %>
In controller your variable is #assessments but for iteration you are trying to use #assessment which is missing plural s. Try as following
<% #assessments.each do |assessment| %>
<% assessment.measurements.each do |m| %>
...
<% end %>
<% end %>
Or, you must need an #assessment instance variable in your controller action. and then you can use following loop
<% #assessment.measurements.each do |m| %>
...
<% end %>
Try to this if you have an association with measurements
#assessments = Assessments.joins(:measurements)
and in your view do this
#assessments.each do |assessment|
assessment.measurements.each do |measurement|
perform operations
end
end
As I mentioned above, I wrote the following code in index action:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
But that was wrong, because I am trying to access #assessment, where the #assessment defined in show action, not in index action. In index all assessments are defined, not a specific one. And I need just one with a specific id.
Also, putting the code in show method instead of index solved the problem.

Display new.html.erb as a partial in index.html.erb

Is there a way to display the new.html.erb form_for div in index.html.erb?
I'd like to be able to add a new entry without leaving the homepage. Maybe a partial?
You can't render part of the template, only whole templete.
If you have a part that same for several templates, than put it to the partial and render partial as part of the template.
This is very simple example:
_partial.rb:
<%= form_for ... %>
...
<% end %>
new.html.erb:
render 'partial'
index.html.erb:
render 'partial'
More about partials and rendering you can read in rails guides.
I got it to work by creating a #article = Article.create in the index module of the controller. Works like a charm. No partials needed.
This method works for me.
In the links_controller.rb I added the #link to the index controller
def index
#links = Link.all
#link = Link.new
end
In the index.html.erb I added only the partial
<%= render 'form' %>
Ended up with the screen of this:
Yes partial would be better in that case. You can have a partial for that "_form.html.erb".
In that partial just put the form_for content. Let you have a Blog model and in the index you are showing the blog lists.
def index
#blog = Blog.new
#your rest code goes here
end
index.html.erb
<YOUR HTML CONTENT>
<%= render "/blogs/form" %>
_form.html.erb
<%= form_for(#blog) do |f| %>
Your code for the form
<%= end %>
If you want to keep the new action will show only the form, then you need to change the action and new.html.erb
def new
#blog = Blog.new
end
In new.html.erb
<%= render '/blogs/form' %>

Rendering action

I'm trying to render an action in my application.html.erb layout file to display it as a modal box using some jquery scripts. I've heard that i can use render :template => 'spots/new' but it looks like this method is not rendering an action but just a view file.
spots#new
def new
#spot = Spot.new
end
new.html.erb
<%= form_for(#spot) do |f| %>
...
<% end %>
The problem is that when i'm trying to render spots#new with render :template => 'spots/new', i'm getting undefined method 'model_name' for NilClass:Class error. Have you any idea what am i doing wrong ? Thanks in advance
You are correct, render :template => 'spots/new' just renders your view template, it does not call spots#new. You should create #spot instance variable before rendering the template.
In your case probably following code will work:
<% #spot ||= Spot.new %>
<%= form_for(#spot) do |f| %>
...
<% end %>

rails update and create using form template

I would like to know where i am wrong. So i have an form template to edit and update model(more than one)
<%= form_for :Car,#car,:url=>{:controller=>:cargo} do |form| %>
....
<%= form.submit "Save", :class => "submit" ,:class =>"Button_style"%>
<% end %>
And in controller(cargo) i have some method
def index
#cars=Car.find_all_by_UserId(session[:user_id])
if #cars.nil?
end
end
def create_auto
#car = Car.new(params[:Car])
#car.UserId=session[:user_id];
if #car.save
redirect_to :action=>:index
else
render :action => "new_auto"
end
end
def new_auto
#car = Car.new
#car.CarProperty.build
end
def edit_auto
#car = Car.find(params[:id])
if #car.nil?
flash[:notice] = "Empty request"
end
end
def update_auto
#car = Car.find(params[:id])
if #car.update_attributes(params[:Car])
else
render :action => "edit_auto"
end
end
To add new car i use button
<%= button_to "Add car",{:action=>:new_auto},{:class =>"Button_style",:method => "get"} %>
To edit
<%= button_to 'Change', :controller=>:cargo,:action=>:edit_auto,:id=>car.CarId %>
But when i press Save button nothings happen I mean create_auto and save_auto are not run
Honestly, you need to take a step back and learn some Rails conventions, such as method names for RESTful controllers.
Rails, more than many frameworks, will bite you really hard if you fight its conventions. This is usually a good thing, as it can allow for great productivity by not reinventing the wheel all the time, but you need to learn them.
I recommend these resources (no pun intended!):
ActionController Overview
Rails Routing from the Outside In
You are using non-conventional method names. If you want to do so, you'll have to specify them in the form. Otherwise I'd suggest to rename the methods to match rails conventions.
create, update, …

Ruby on Rails -Problem using subdirectories

I have tried to set up a separate section of my app using a subdirectory called controlpanel to manage various parts of the site.
I've set up the namespace in my routes.rb
map.namespace :controlpanel do |submap|
submap.resources :pages
# other controllers
end
And placed the controller and views into the relevant subdirectories.
Controlpanel::PagesController
def new
#page = Page.new
end
def create
if #page = Page.create_with_author(current_user, params[:page])
flash[:notice] = 'Page was successfully created.'
redirect_to ([:controlpanel, #page])
else
render :action => 'new'
end
end
Using this mixed in class method
def create_with_author(author, params)
created = new(params)
created.author = author
if created.save
created
end
end
And the view (controlpanel/pages/new.html.erb renders a partial called _form
<%= render :partial => 'form' %>
Which is as follows:
<% semantic_form_for([:controlpanel, #page]) do |form| %>
<% form.inputs do %>
<%= form.input :title %>
<%= form.input :body %>
<% end %>
<%= form.buttons %>
<% end %>
If I fill in the form correctly, it works as expected, redirecting me to the new page, however, if I leave fields blank, violating the validation constraints, I get the following error:
RuntimeError in Controlpanel/pages#create
Showing app/views/controlpanel/pages/_form.html.erb where line #1 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Can anyone see what is going wrong?
I'm using the formtastic plugin to create the form, but it still happens if I use a regular form.
Any advice greatly appreciated.
Thanks.
Given that the create action is called and new is rendered, Page.create must evaluate to nil.
You probably want to pass params[:page] to create.

Resources