Rails: How Does "New" Action Called "Create" Action

Rails : How does new action called create action?

It's not passed to create action, it's instantiated again with params you pass from the form displayed with new action.

create action is called with POST request to the path specified in config/routes.rb, leading to specific controller and action.

How is the 'new' action redirected to 'create' in Rails?

OOP

The bottom line answer to your question is that Rails is object orientated (by virtue of being built on top of Ruby). This is very important, as it means everything inside Rails should be based around objects:

Sample Image

This leads me to the routes - the resourceful nature of Rails' routes is down to the same idea, that you need to work with objects in your application - hence the resources directive providing 7 key actions to manipulate those objects

To fully understand Rails, you really need to look into how it works with objects, specifically how they interact with each other


Redirect

To answer your question regarding the redirect, the simple answer is that Rails doesn't "redirect" to any action specifically

Remember, Rails is stateless - it does not persist data through requests - it only has the data which you either initialize at the time, or have sent it

What you're confused about is how some of the Rails actions seem to be sending your requests to the appropriate "request" action. The answer to this lies in the helpers / methods you use, specifically form_for


form_for

form_for builds forms from their ActiveRecord objects.

Therefore, if you perform the following:

#app/controllers/your_controller.rb
Class YourController < ActiveRecord::Base
def new
@model = Model.new
end
end

This will give Rails the knowledge that it's loading a new object, and therefore will use the form_for method to send the request to the create action

If you used form_tag, you would not get a redirect to the create action -- that's the magic of Rails -- it's been built to accommodate objects

How do I create a new/create action for items?

resources :users do
resources :items, only: [:new, :create]
end

This will nest items route inside user. Check rake routes and you will not get this items_path

You have to define resource :items to get items_path

So if you want to use nested routes you have to update your form and controller and if not just routes resource :items

<%= form_for [@user, @item] do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>

<%= f.submit "Save" %>
<% end %>

and controller

def new
@item = Item.new
@user = current_user
end

How are params passed from the New to Create action in Rails?

You are mixing two requests with each other. When you hit the new action, a view that contains your form gets rendered. As it gets rendered, the new action finishes, and now the new action has nothing to do with create action.

You need new action to create a form through form_for method in which you actually pass an object, in your case @post.

The create action is independent, and params it receives, they have nothing to do with new method, those params are received through form rendered in the new.html.erb file of views.

You can also invoke the create method in your controller by sending the data through AJAX or even using cURL or POSTMAN - a chrome extension.

And as you asked:

How does rails channel these params to create despite the page refresh that occurs?

Rails doesn't channel these params, Rails run at back-end, Rails just receives those params. They are sent through an HTML form, and as I said earlier there are other ways to send params as well.

Rails - How does the show and new action work

Render produces a string that will displayed as the response to the request to the application.

redirect_to produces a response header resulting in a new request to the application.

The render action 'show', location: @product uses the the file app/views/products/show.html.erb with @product as a parameter to produce the html which will be returned.

The reason some of the controller functions are empty is that rails are using defaults. So if you don't tell rails what to render then rails will look for a file in the appropriate location.

Methods ending with redirect_to are usually post/patch requests saving something in your database and after the requested action has been performed they redirect the user to a method meant for displaying information.

Rails new vs create

Within Rails' implementation of REST new and create are treated differently.

An HTTP GET to /resources/new is intended to render a form suitable for creating a new resource, which it does by calling the new action within the controller, which creates a new unsaved record and renders the form.

An HTTP POST to /resources takes the record created as part of the new action and passes it to the create action within the controller, which then attempts to save it to the database.

Rails form going to new action instead of create action

form_for @parent, :url => leads_path, :method => "post"

Also, you don't need the form tag wrapped around the outside, form_for generates its own form tag

Call create action from different controller

Your mistake is inside if-else in the controller. You're checking @room before you define it, so it is always nil. It should be:

def create
# use find_by here, otherwise you get RecordNotFound error
@room = Room.find_by(id: params[:room_id])
if @room
# use build, because create saves the instance
@booking = @room.bookings.build(booking_params)
if @booking.save
redirect_to room_path(@room)
else
# I suppose you don't want render bookings/new view here
render 'books/show'
end
else
@booking = Booking.new(booking_params)
respond_to do |format|
# redirect and render logic goes here. BTW, do you really need json response format?
end
end
end
end

Also, define in rooms#show action

@booking = @room.bookings.build

and use the instance in the form to correctly display validation errors

form_with(model: [@room, @booking], local: true) do |form| 

create action in rails

By default scaffolding on form (read here)

When the user clicks the Create Post button on this form, the browser
will send information back to the create action of the controller
(Rails knows to call the create action because the form is sent with
an HTTP POST request; that’s one of the conventions that were
mentioned earlier):

def create
@post = Post.new(params[:post])

respond_to do |format|
if @post.save
format.html { redirect_to(@post,
:notice => 'Post was successfully created.') }
format.json { render :json => @post,
:status => :created, :location => @post }
else
format.html { render :action => "new" }
format.json { render :json => @post.errors,
:status => :unprocessable_entity }
end
end
end

If you want customize an action on new form scaffold, you should add :url => {:action => "YourActionName"} on your form.

Example :

#form
form_for @post, :url => {:action => "YourActionName"}

#controller
def YourActionName
@post = Post.new(params[:post])

respond_to do |format|
if @post.save
format.html { redirect_to(@post,
:notice => 'Post was successfully created.') }
format.json { render :json => @post,
:status => :created, :location => @post }
else
format.html { render :action => "new" }
format.json { render :json => @post.errors,
:status => :unprocessable_entity }
end
end
end

#route
match '/posts/YourActionName`, 'controllers#YourActionName', :via => :post

Rails Call 'Create' Action from Another Controller

Move this method to application_controller.rb and allow to pass params to it.

Then you'll be able to call it from any controller method



Related Topics



Leave a reply



Submit