Git Product home page Git Product logo

rails-create-action-readme's Introduction

Create Action

Setup

In this lesson, we'll be using some existing code to explore the create action in Rails. To get the app set up, run:

$ bundle install

Creating Records

In this lesson, we'll code a create action — 'C' in the 'CRUD' life cycle — that saves a new Post object and then redirects to the newly-created post's show page.

Before implementing this functionality, let's first open up a Rails console session and create a record manually.

First, run rails c to enter a console, then enter the following lines one at a time:

post = Post.new
post.title = "Title Goes Here"
post.description = "Desc goes here..."
post.save

This syntax will let you manually create a new Post record with title and description attributes. After running the save method in the console, you will see output similar to the following:

 (0.1ms)  begin transaction
SQL (0.3ms) INSERT INTO "posts" ("title", "description", "created_at", "updated_at")
VALUES (?, ?, ?, ?)  [["title", "Title Goes Here"], ["description", "Desc goes here..."], ["created_at", "2015-11-23 22:26:43.799742"], ["updated_at", "2015-11-23 22:26:43.799742"]]
 (1.2ms)  commit transaction
=> true

As you can see, the save method generates a SQL script that inserts a new record into the database. Each of the Post object's attributes is passed into the SQL statement, and the method returns true upon a successful save. At a high level, this is what the create method in our PostsController will be doing.

Now that we've created a post manually, exit the Rails console by typing exit or pressing Control + d.

Defining a Create Action

Open up the posts_controller.rb file. Let's do a few things to replicate the behavior we had in the console:

  1. Create a new Post instance

  2. Pass in the parameters from the form

  3. Save the record

To build this behavior initially, let's copy and paste the code that we ran in the console. The only key difference is that now, instead of assigning post.title and post.description manually, we want to be able to pull in form data - stuff that a user has typed in and submitted. As long as the form is properly connected to the controller and model, we can populate the title and description attributes based on the user input:

# app/controllers/posts_controller.rb
def create
  post = Post.new
  post.title = params[:title]
  post.description = params[:description]
  post.save
end

You can access each of input values in a form using the hash syntax to grab the elements from the params hash. When a user submits a form, it is the params hash that contains all the input data. As long as the form is routed to the create method we've written (in config/routes.rb), we'll be able to initialize a new instance of Post, grab those input values from params, assign them the post instance attributes and save the instance to our database.

We've already got the route and our form created. Let's explore this functionality by running the server with rails s. If you go to /posts/new, fill out the form, and submit it, you'll get the message shown below in your terminal:

   (0.3ms)  begin transaction
  SQL (1.1ms)  INSERT INTO "posts" ("title", "description", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["title", "A new post"], ["description", "desc"], ["created_at", "2022-01-06 16:12:44.564952"], ["updated_at", "2022-01-06 16:12:44.564952"]]
   (1.7ms)  commit transaction
No template found for PostsController#create, rendering head :no_content
Completed 204 No Content in 39ms (ActiveRecord: 3.0ms)

Great! Our record was created. The last line of the terminal output, No template found for PostsController#create simply means that Rails can't find a create view template since, by default, it's trying to render a template called create.html.erb (which doesn't exist). Remember, Rails tries to map each controller action directly to a template. However, with actions like create, we don't want a view template –– all we want is for the action to communicate with the database and then redirect to a different page.

In the console, you'll see that the record was successfully created in the database even though we didn't see anything change in the browser. Our form and create action are working properly. How do we know the record was successfully created? There are a couple of ways to check:

  1. Type Post.last into the Rails console, and it will display the most recently created record. We can look at the record's created_at attribute to ensure the timestamp is current.

  2. We can also simply scroll up through the Rails server logs. All SQL statements are printed out in the log, so it's just a matter of locating the correct INSERT statement (example below):

 (0.1ms)  begin transaction
SQL (0.7ms)  INSERT INTO "posts" ("title", "description", "created_at", "updated_at")
VALUES (?, ?, ?, ?)  [["title", "My Post"], ["description", "My desc"], ["created_at", "2015-12-26 18:00:31.393419"], ["updated_at", "2015-12-26 18:00:31.393419"]]
 (2.2ms)  commit transaction

Redirecting After Create

To fix the 'missing template' error, we simply need to redirect the user after they've filled out the form. Let's do two refactors:

  • Update the code with a redirect that leverages a route helper method

  • Refactor the post variable into an instance variable

The revised create method should look something like this:

def create
  @post = Post.new
  @post.title = params[:title]
  @post.description = params[:description]
  @post.save
  redirect_to post_path(@post)
end

In this refactored create action, we're following the convention of redirecting to the new resource's show page. It stands to reason that a user who submits a new post would then like to view the successfully-created post. With that being said, the page flow is not set in stone, and we could've redirected the create action to the index action just as easily.

All our tests should be passing now, and the site is working in the browser. Users are able to create records in the database using the HTML form, and, upon submitting a new post, they're automatically redirected to the show page for the post they just created. In future lessons, we'll refactor this further to incorporate awesome Rails components like strong parameters and error handling, but don't worry about those yet. Great job!

rails-create-action-readme's People

Contributors

annjohn avatar danielseehausen avatar drakeltheryuujin avatar dstoll243 avatar franknowinski avatar ihollander avatar jordanhudgens avatar maxwellbenton avatar mendelb avatar pletcher avatar preetness avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rails-create-action-readme's Issues

solution a little too advanced for this stage?

Just thought i'd comment here - the way the lab was solved in the answer is super different from the way the rails lessons have ramped us up. Obvs theres a million ways to do stuff it just felt like it was a bit more shortcuts than one can infer at the beginning stages of rails.

No Routes Written, despite instructions

Hey there. In the ReadMe it says, We've already got the route and our form created. If you go to /posts/new, fill out the form, and submit it, you'll get the error shown below. but there are no routes written. Just update that or add the route code to add.

rails-create-action-readme

Canvas Link

https://learning.flatironschool.com/courses/1881/assignments/125519?module_item_id=259387

Concern

I did not like the lesson, the directions on the lesson weren't clear and, I believe one thing was said and you meant something else. The directions I tried didn't fix the errors. I'm not sure whats going on with the rails lessons but these are not working correctly along with the lessons being unclear.

Additional Context

def create
post = Post.new
post.title = params[:title]
post.description = params[:description]
post.save
redirect_to post_path(post)
end

Issues such as this. In the lesson you stated to put @post inside the post_path, which brought up the error instead of passing it. I had to actually change it to post.

Suggested Changes

No response

This lesson should be updated for Rails 5 and above.

Hi. I think part of this lesson applies only to versions of Rails below version 5. Near the bottom, it has you make your create method like this:

def create
  post = Post.new
  post.title = params[:title]
  post.description = params[:description]
  post.save
end

It then says that when you make a new post in the form and submit it, you will get a "Template is missing error", since Rails is looking for a nonexistent create.html.erb file.

When I tried that out (with Rails 5.0.7.2), I didn't get that error. Instead, the page simply didn't go anywhere, and my console received this output:

No template found for PostsController#create, rendering head :no_content
Completed 204 No Content in 198ms (ActiveRecord: 3.4ms)

This isn't a huge issue, but it might confuse students who are using Rails 5 and newer. As always, thanks for looking into this!

---Sdcrouse

Using @post instead of post in the redirect.

def create
  @post = Post.new
  @post.title = params[:title]
  @post.description = params[:description]
  @post.save
  redirect_to post_path(@post)
end

The redirect in this line should be changed to 'post' from @post. Otherwise the specs fail with this error:

form
  shows a new form that submits content and redirects and prints out params (FAILED - 1)

Failures:

  1) form shows a new form that submits content and redirects and prints out params
     Failure/Error: redirect_to post_path(@post)

     ActionController::UrlGenerationError:
       No route matches {:action=>"show", :controller=>"posts", :id=>nil} missing required keys: [:id]

rails console issue

i can get rails to work with sqlite2 by dropping the rails version and specifying the sqlite3 version '~> 1.3.6'.
But rails console won't work, with this error:

/usr/local/rvm/gems/ruby-2.3.1/gems/railties-5.0.7.1/lib/rails/commands/console.rb:20:in `block in parse_arguments'
: invalid option: -b (OptionParser::InvalidOption)

possible broken lab

i followed the readme carefully step by step but dont get the error message missing template. after clicking submit on the form nothing happens. i also get

  1. form shows a new form that submits content and redirects and prints out params
    Failure/Error: redirect_to post_path(@post)

    ActionController::UrlGenerationError:
    No route matches {:action=>"show", :controller=>"posts", :id=>nil} missing required keys: [:id]

as an error but in the routes file it has resources posts

missing routes in route.rb

It seems that no route was added to route.rb in the config file despite the below sentence in the readme

"As long as the form is routed to the create method we've written (in config/routes.rb), we'll be able to initialize a new instance of Post, grab those input values from params, assign them the post instance attributes and save the instance to our database."

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.