Rails Routing: Two actions to point to the same view - ruby-on-rails

I'm trying to create two actions that both go to the "new" view. The only difference is I would like the new_e_drawing action to run the incrament_e method, whereas the new action runs the incrament method.
def new
#drawing = Drawing.new
#drawing = #drawing.incrament(#drawing)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #drawing }
end
end
def new_e_drawing
#drawing = Drawing.new
#drawing = #drawing.incrament_e(#drawing)
respond_to do |format|
format.html new.html.erb
format.json { render json: #drawing }
end
end
I would like both of them to take me to the view named "new". I'm not sure how to set up the routing or the respond_to statement for the new_e_drawing action. I tried these with no success:
get 'drawings/new' => 'drawings#new_e_drawing'
match 'drawings/new_e_drawing' => 'drawings#new_e_drawing'
Thanks for the help.

Render the "new" template explicitly in your html block of new_e_drawing action.
def new
#drawing = Drawing.new
#drawing = #drawing.incrament(#drawing)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #drawing }
end
end
def new_e_drawing
#drawing = Drawing.new
#drawing = #drawing.incrament_e(#drawing)
respond_to do |format|
format.html { render :template => "new" }
format.json { render json: #drawing }
end
end
In your routes,
match 'drawings/new_e_drawing' => 'drawings#new_e_drawing'
route for new action will be automatically generated by rails since it is part of CRUD

Related

Not able to update data in database form

I am getting error - undefined method collect for nil:NilClass, but I am able to render option list from another database table, and also able to save data in stage table but not able to update it.
I am rendering option list form responsibility table in stage form field responsibility option and saves that option into stage table.
stages_controller.rb
def index
redirect_to project_path(#project)
end
def show
end
def new
#stage = Stage.new
#responsibilities = #project.responsibilities
end
def edit
end
def create
#responsibilities = #project.responsibilities
#stage = #project.stages.build(stage_params)
respond_to do |format|
if #stage.save
format.html { redirect_to project_path(#project), notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def update
#responsibilities = #project.responsibilities
respond_to do |format|
if #stage.update(stage_params)
format.html { redirect_to project_stages_url, notice: 'Stage was successfully updated.' }
format.json { render :show, status: :ok, location: #stage }
else
format.html { render :edit }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def destroy
#stage.destroy
respond_to do |format|
format.html { redirect_to project_stages_url, notice: 'Stage was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_stage
#stage = Stage.find(params[:id])
end
def find_project
#project = Project.find(params[:project_id])
end
your edit method is empty, so #responsibility has no content (null), you can put some code for example (from your other method)
def edit
#project = Project.find(params[:id])
#responsibilities = #project.responsibilities
...
end
The issue here is that #responsibilities is not defined in your partial.
You should pass the local variable to the partial like this -
<%= render partial: "form", locals: {responsibilities: # responsibilities} %>
and then you can use responsibilities inside the form partial
More about passing variable to partials

Why does Rails controller not have an if statement to check if destroy was successful?

I noticed that the default controller generated by rails has if statements in create and update but not in destroy
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
No if statement in case the destroy fails
def destroy
#product = Product.find(params[:id])
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
Here is the rest of the scaffolded controller.
class ProductsController < ApplicationController
# GET /products
# GET /products.json
def index
#products = Product.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #products }
end
end
# GET /products/1
# GET /products/1.json
def show
#product = Product.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #product }
end
end
# GET /products/new
# GET /products/new.json
def new
#product = Product.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #product }
end
end
# GET /products/1/edit
def edit
#product = Product.find(params[:id])
end
# POST /products
# POST /products.json
def create
#product = Product.new(params[:product])
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render json: #product, status: :created, location: #product }
else
format.html { render action: "new" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PUT /products/1
# PUT /products/1.json
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product = Product.find(params[:id])
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
end
Why does Rails controller not have an IF statement in destroy method by default?
When using create or update, there is a chance that the data will not match the requirements. For example, if you try to insert a nil value into a column with NOT NULL, or if a value isn't within a range specified by a Rails validate method.
In these instances, if we fail to save the data, we want to respond accordingly, such as with a new input form where the user can make corrections, etc. But if succeeds, we typically redirect to the show page.
When using destroy, on the other hand, we're normally removing a row from the database. Since this process doesn't include any validation, there's no (or, perhaps, very little) concern that things will go wrong. So in this situation, we don't need the if statement, and we can proceed without caution.

How render to another view other than the default view

I need the block respond_to not render to new.html.erb if not a another view created by me called for example new_form.html.erb
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
Pretty simple. As long as the view is in the default directory for the controller:
respond_to do |format|
format.html render 'new'
format.json { render json: #user }
end
If not, you need to tell it which directory:
respond_to do |format|
format.html render 'users/new'
format.json { render json: #user }
end
More docs here: http://guides.rubyonrails.org/layouts_and_rendering.html
There are many ways to do it....
##FOR HTML CALLS
format.html { render 'new'}
format.html { render 'shared/new'}
##FOR JS CALLS
format.js { render 'new'}
format.js { render 'shared/new'}
##pass variable to the view
format.js { render 'shared/new',:locals=>{:type=>"User"}}
##OR you can also try redirect in some rare cases WITHOUT respond_to block
redirect_to users_path(params[:id])

Why Doesn't Rails Scaffold Include Json Rendering for Edit in Controller?

This is just out of curiosity, here's a generated controller from running rails g scaffold Thing:
class ThingsController < ApplicationController
# GET /things
# GET /things.json
def index
#things = Thing.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #things }
end
end
# GET /things/1
# GET /things/1.json
def show
#thing = Thing.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #thing }
end
end
# GET /things/new
# GET /things/new.json
def new
#thing = Thing.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #thing }
end
end
# GET /things/1/edit
def edit
#thing = Thing.find(params[:id])
end
# POST /things
# POST /things.json
def create
#thing = Thing.new(params[:thing])
respond_to do |format|
if #thing.save
format.html { redirect_to #thing, notice: 'Thing was successfully created.' }
format.json { render json: #thing, status: :created, location: #thing }
else
format.html { render action: "new" }
format.json { render json: #thing.errors, status: :unprocessable_entity }
end
end
end
# PUT /things/1
# PUT /things/1.json
def update
#thing = Thing.find(params[:id])
respond_to do |format|
if #thing.update_attributes(params[:thing])
format.html { redirect_to #thing, notice: 'Thing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #thing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /things/1
# DELETE /things/1.json
def destroy
#thing = Thing.find(params[:id])
#thing.destroy
respond_to do |format|
format.html { redirect_to things_url }
format.json { head :no_content }
end
end
end
Rails includes a format block in every action except for edit... Why is this? Theoretically another app pinging the server for json would still want to show whatever is being edited, right? It's easy enough to just add in, but I am curious why they chose to do it this way.
If you want to know what you are updating, you can do it via the show action.

void respond_to format.html Only should works with format.js

I want void format.html response in controller in ruby on rails 3.
e.g. in my comments_controller.rb
def new
#comment = Comment.new
respond_to do |format|
#format.html # new.html.erb avoid this output
#format.json { render json: #board } # avoid this output
format.js
end
end
I want only works with format.js response and after, render partial from new.js.erb. This is not problem for me its easy, but...
If I put:
http://localhost:3000/comments/new
I get a blank page :O.
How can I void this page? e.g. render or show a error 404.
Thank you!
You can do something like:
def new
#comment = Comment.new
respond_to do |format|
format.html { render text: "Error", status: 404 }
#format.json { render json: #board } # avoid this output
format.js
end
end
See http://guides.rubyonrails.org/layouts_and_rendering.html for full details.

Resources