Code Monkey home page Code Monkey logo

sinatra-ar-crud-lab's Introduction

Sinatra Active Record CRUD Lab

Learning Goals

  1. Implement all four CRUD actions in a Sinatra application.
  2. Understand how each CRUD action corresponds to a controller action and POST request.

Instructions

We've had a lot of practice with the ActiveRecord CRUD actions, so now it's time to tie them to controller actions in a Sinatra application. In this lab, you'll be building a basic magazine app, using every CRUD action.

Important: In Sinatra, the order in which you define your routes in a controller matters. Routes are matched in the order they are defined. So, if we were to define the get '/articles/:id' route before the get '/articles/new' route, Sinatra would feed all requests for /articles/new to the /articles/:id route and we should see an error telling us that your app is unable to find an Article instance with an id of "new". The takeaway is that you should define your /articles/new route before your /articles/:id route.

Database

First, you'll need to create the articles table. An article should have a title (string) and content (string).

Next, set up the corresponding Article model. Make sure the class inherits from ActiveRecord::Base.

If you've done everything correctly, you should be able to run rake db:seed to populate your database with a few sample articles. Spend some time in rake console and make sure you know how to retrieve all of the articles as well as get a single article using its id. Create at least one article of your own from inside the console.

Read

The Read CRUD action corresponds to two different controller actions: show and index. The show action should render the ERB view show.erb, which shows an individual article. The index action should render the ERB view index.erb, which shows a list of all of the articles.

Create the get '/articles' controller action. This action should use Active Record to grab all of the articles and store them in an instance variable, @articles. Then, it should render the index.erb view. That view should use ERB to iterate over @articles and render them on the page.

Create the get '/articles/:id' controller action. This action should use Active Record to grab the article with the id that is in the params and set it equal to @article. Then, it should render the show.erb view page. That view should use ERB to render the @article's title and content.

Create

Now it's time to set up the ability to create an article.

First, create a route in your controller: get '/articles/new', that renders the new.erb view. This view will be a blank form that should submit a POST request to /articles. (Look up the method and action attributes for HTML forms if you aren't sure how to do this).

Now you will need to tell your controller what to do when your form sends that POST request, so create a route on your controller post '/articles' that creates a new article from the params from the form, then redirects to that new article's show page.

Update

The Update CRUD action corresponds to the edit controller action and view.

Create a controller action, get '/articles/:id/edit', that renders the view edit.erb. This view should contain a form to update a specific article--similar to the form you made for a new article, but the fields should be pre-populated with the existing title and content of the article.

Define the controller action patch '/articles/:id'. Although we want to send a PATCH request to /articles/:id to process the form, we have to be a little sneaky to trick HTML into letting us do something besides a GET or a POST.
Your form will be configured to send a POST request in its method attribute, but then we'll have Sinatra override it: Inside the form itself, add a hidden field to specify a PATCH request like so:

<input id="hidden" type="hidden" name="_method" value="PATCH">

Reminder: Add the use Rack::MethodOverride to your config.ru file so that your app will know how to handle PATCH, PUT, and DELETE requests!

(This is confusing and weird, and you should ask questions about it!)

Delete

The Delete CRUD action corresponds to the delete controller action, delete '/articles/:id'. To initiate this action, we'll add a "delete" button to the show page (i.e., deleting won't have its own view). This button will be in a form, but the form won't have any other fields in it... just the single button. The form will send a request to the delete controller action, where we will identify the article to delete and delete it. Then, the action should redirect to the index of all articles โ€” we can't go back to the show page, since the article has been deleted!

Making our Delete "Button"

Give your form tag a method of POST and an action of "/articles/:id'. Make sure to dynamically set the :id of the form action to reflect the id of the article you're editing! You'll also need to make sure the form includes the hidden input tag to change the request from POST to DELETE, similar to how we constructed the PATCH request above

sinatra-ar-crud-lab's People

Contributors

annjohn avatar aviflombaum avatar dakotalmartinez avatar dalmaboros avatar davdkm avatar dependabot[bot] avatar drakeltheryuujin avatar hellorupa avatar ihollander avatar jd2rogers2 avatar jmburges avatar kaileeagray avatar lcorr8 avatar lizbur10 avatar lukeghenco avatar maxwellbenton avatar nolyoi avatar pletcher avatar preetness avatar rishter avatar rrcobb avatar sophiedebenedetto avatar telegraham avatar victhevenot avatar yehudamakarov avatar

Stargazers

 avatar

Watchers

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

sinatra-ar-crud-lab's Issues

submitting labs

Im having an issue submitting this lab. Is this because I changed the username on my github account? please help my other labs wont submit either
512-299-5558

sinatra-ar-crud-lab-v-000 git:(master) learn submit
Adding changes...
Committing changes...
Sorry, something went wrong. Please try again.

delete action doesn't make sense

Delete action should be a button (i.e. form) on the post's show page that posts to the delete controller action. Not its own erb view with only a delete button and no other info about the given post you want to delete. Also instructions are unclear that the tests require making a separate delete.erb view.

Expect Issue in Sinatra AR Lab delete route

During the test suite, I was getting an error for my delete route because the expected output was suppose to be "Hello World" but the using binding.pry. I checked all the articles using Article.all to view all the articles saved and I saw "Hello World!!!!" not the expected "Hello World."

Misprint

The instructions say we should create a table with the name "Articles", but it is referring to the one that's already been created named "Posts".

Update and Delete sections need more clarification

The curriculum doesn't cover what the following things mean:

use Rack::MethodOverride

In general, the update and delete actions are difficult to execute/understand, since there isn't anything in the curriculum that explains these. There is context for completing the Create and Read actions, but not enough for Update and Delete.

Consider using a different model?

For someone just getting into Sinatra + AR, this is a really confusing first lab because the word "post" is used for blog posts but also as an http verb & also as a class name and it's too early to be given this cognitive load.

Incorrect Ruby version will cause Arel error.

Student was using Ruby version 2.4.2 which was causing an Arel error.

1) Blog Post App Create Action creates a new blog post
     Failure/Error: expect(Post.last.name).to eq("my favorite blog post")

     TypeError:
       Cannot visit Integer

Switching to Ruby version 2.3.1 with RVM solved the issue.

Student was using a local environment. Not the IDE.

Expect Issue in Sinatra AR Lab delete route

It created "Hello World!!!" as an article at the beginning of the tests. In the end, it only checks for "Hello World" without the exclamation marks. See "sinatra_ar_crud_lab_spec.rb" line 127

NotImplementedError

When running learn or shotgun an error appears -
in fork': fork() function is unimplemented on this machine (NotImplementedError)`

Test pass and labs submit without issue but, without being able to run shot gun its difficult to work through bugs without actually seeing it run.

Delete CRUD Action Mismatch

Delete CRUD instructions say to delete the instance then redirect to /posts/ route but tests within lab test for a delete.erb page which displays a confirmation message of "x was deleted."

To fix, have rspec test for redirect to posts OR have instruction indicate there should be a delete.erb page created and remove part about making a redirect to posts.

Let me know if I just misread it wrong. ;)

'database_cleaner' gem errors

Hi, the Gemfile in this lab includes

gem 'database_cleaner', git: 'https://github.com/bmabey/database_cleaner.git'

When students run the learn command, all of the tests raise an error (and all pointing to the database_cleaner gem). I tried replacing the gem with

gem 'database_cleaner', '1.0.0.RC1'

but the tests still raise an error on the database_cleaner.

Your Gemfile lists the gem sqlite3 (>= 0) more than once. You should probably keep only one of them. While it's not a problem now, it could cause errors if you change the version of one of them later.

Your Gemfile lists the gem sqlite3 (>= 0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of one of them later.
Your Gemfile lists the gem pry (>= 0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of one of them later.
Your Gemfile lists the gem tux (>= 0) more than once.
You should probably keep only one of them.
While it's not a problem now, it could cause errors if you change the version of one of them later.
Your Gemfile lists the gem capybara (>= 0) more than once.

Solution?
https://stackoverflow.com/questions/21621604/your-gemfile-lists-the-gem-more-than-once-could-cause-errors?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

readme describes the "delete" function one way, but the test requires a different way

README states:
DELETE
The Delete CRUD action corresponds to the delete controller action, delete '/posts/:id/delete'. However, we won't make a specific "delete" view page, as that isn't really conventional. Instead, we'll just add a "delete button" to the show page. This "button" will actually be a form, disguised as a button (intriguing, I know). The form will send a POST request to the delete controller action, where we will identify the post to delete and delete it. Then, the action should redirect to the get '/posts' route.

However, if you do it that way, one of the tests won't pass.
delete action test:
displays a view telling us which post was deleted

use Rack::MethodOverride not necessary?

Hi Learn,

The instructions underneath the update section state:
"Reminder: Remember to add the use Rack::MethodOverride to your config.ru file so that your app will know how to handle patch and delete requests!"

However, when I actually added this to my config.ru file my code was not working as expected. There was no error getting thrown but when the post '/posts/:id' action was getting called the page was not displaying and the post was not getting updated.

As soon as I commented this line out everything worked perfectly. I tried to see if this line of code was in any other part of the project but could not find it. Therefore, I think that the instruction is in need of an update.

Best,

Denise

instructions not clear or detailed enough

This is the first time students will be building CRUD actions into a Sinatra app. They've never seen clear examples of this before because this lab is not preceded by a walk-through or code-along and the instructions are not clear enough. For example, instructions for the "Create" portion of the app should detail the connections between the get '/posts/new' route, the new.erb view and the post '/posts' route. Ditto for "Read", "Update" and "Delete".

Instructions in the DELETE paragraph are misleading

The last line of instructions in the DELETE paragraph states -

Then, the action should redirect to the get '/posts' route.

However, the spec tests require creation of an additional view showing deletion confirmation to be displayed with @post.name after a post has been deleted. This cannot be easily achieved by get '/posts' route, as the post would have already been destroyed, and would not be part of Post.all anymore.

So ideally, there is no way to redirect to get '/posts' route, unless an additional link is provided in the deletion confirmation page to redirect to get '/posts' route.

Either the instructions or the spec tests need to be fixed to correct this misalignment. Unless, of course this is some sort of a teaser test for the students.

Reopening an issue about redirecting

Hi. I am reopening this previously resolved issue: #17

This lab requires us to redirect to other pages, even though redirecting hasn't been covered yet. While it is true that redirecting is used in a previous video review lesson (https://learn.co/tracks/full-stack-web-development-v7/sinatra/forms/lab-review-sinatra-nested-forms-lab-pirates), it isn't introduced until the next lesson (User Authentication in Sinatra).

Since redirecting is crucial to this lab, it would help to either discuss how to do that, or else put the lab further down in the curriculum.

Thanks for looking into this!

---Sdcrouse

uninitialized constant DatabaseCleaner::ActiveRecord

I'm having students unable to pass this lab due to the DatabaseCleaner setup in this lab.
This is the error that most students are getting.

Failure/Error: DatabaseCleaner.strategy = :transaction

NameError:
  uninitialized constant DatabaseCleaner::ActiveRecord

Lab Order

The order of these labs makes the first CRUD lab very difficult to navigate with the little information provided before hand. A partner and I sat for hours, and we only got more lost as we went. Once I moved on, I understood the concept and could complete the labs.

Can't run shotgun

Forked repo, ran migrations, and then running shotgun returns this error:

`Boot Error
Something went wrong while loading config.ru

SystemExit: exit
config.ru:12:in 'exit'
config.ru:12:in 'rescue in block in inner_app'
config.ru:4:in 'block in inner_app'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/builder.rb:55:in 'instance_eval'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/builder.rb:55:in 'initialize'
config.ru:1:in 'new'
config.ru:1:in 'inner_app'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:113:in 'eval'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:113:in 'inner_app'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:103:in 'assemble_app'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:86:in 'proceed_as_child'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:31:in 'call!'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/loader.rb:18:in 'call'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/favicon.rb:12:in 'call'
/usr/local/rvm/gems/ruby-2.6.1/gems/shotgun-0.9.2/lib/shotgun/static.rb:14:in 'call'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/urlmap.rb:68:in 'block in call'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/urlmap.rb:53:in 'each'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/urlmap.rb:53:in 'call'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/builder.rb:153:in 'call'
/usr/local/rvm/gems/ruby-2.6.1/gems/rack-2.0.4/lib/rack/handler/webrick.rb:86:in 'service'
/usr/local/rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/webrick/httpserver.rb:140:in 'service'
/usr/local/rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/webrick/httpserver.rb:96:in 'run'
/usr/local/rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/webrick/server.rb:307:in 'block in start_thread'`

Confusion over Wording

The wording is a bit unclear. In the README, where it says "the action, pointing to /articles, will trigger a render of an index.erb file automatically. Before we can fully test if our form is working, we need to create that index.erb file, as our site will currently crash upon submission," it was explained to me that this means that the 'post '/articles'' controller should temporarily render index.erb, to avoid failing the corresponding tests. If that is the case, it isn't made very clear in the README. Even after passing the 'get '/articles'' and 'get 'articles/:id'' tests, it was difficult to understand why the Create Action test required a redirect to '/articles/:id'--which renders to show.erb--especially as the README states "pointing to /articles, will trigger a render of an index.erb file automatically." Also, if the index.erb view is meant to display all articles held in the @articles instance variable, created in the 'get '/articles'' controller, would it even have access to the @Article instance variable created in 'post '/articles'' controller?

Would simply changing "will trigger a render of an index.erb file automatically" to "will trigger a render of a show.erb file automatically" make this clearer?

Bug in Capybara "click_button"?

I have working code (validated through the browser and console) with a button for deleting new posts, however the tests that utilize Capybara's click_button method continue to fail, presumably because the button is not being clicked. Some googling indicates that this might be an issue with Capybara, but I'm not sure. Within the test, I've tried using page.find('#delete'), which grabs the correct input, and then using the .click method, but that has no effect either.

Code below:

#show.erb
<h1><%= @post.name %></h1>
<p><%= @post.content %></p>
<form method="POST" action="/posts/<%= @post.id %>/delete" />
  <input id="hidden" type="hidden" name="_method" value="delete"/>
  <input id="delete" type="submit" value="delete"/>
</form>
#application_controller.rb

  delete '/posts/:id/delete' do
    @post = Post.find(params[:id])
    @post.destroy
    erb :'posts/deleted'
  end
#sinatra_ar_crud_lab_spec.rb

    it "deletes a blog post from the database" do
      visit "/posts/#{@post2.id}"
      # page.find('#delete').click # This doesn't work either
    
      expect(Post.all.count).to eq(1)
      expect(Post.last.name).to eq("Hello World")
    end
    
    it "displays a view telling us which post was deleted" do
      visit "/posts/#{@post2.id}"
      click_button "delete"
      expect(page.body).to include("#{@post2.name} was deleted")
    end

CREATE directions Misleading

The directions for the CREATE part of this lab:

CREATE
Now that we have the database and model set up, it's time to set up the ability to create a blog post.
First, create a route in your controller, get '/posts/new', that renders the new.erb view.
We need to create an erb file in the views directory, new.erb, with a form that POSTs to a controller action, /posts. The controller action should use the Create CRUD action to create the blog post and save it to the database. Then, the action uses erb to render the index view page.

The problem I have with the last sentence in this lab is it's telling someone to explicitly use erb in this method. Meaning I would write something like this

post '/posts' do @post = Post.create(params) erb :index end

After this part, comes READ where we write the GET '/posts' method, which prints out all the posts, again, to index.erb. At this point, we have two methods, with directions saying to use index.erb but obviously POST '/posts' will break because index.erb is using instance variables:

@posts = Post.all

POST '/posts' knows nothing about.

The answer is to have POST '/posts' redirect to GET '/posts'. From the previous lessons, it's possible for a student to make this leap on their own or to know that's what should happen next already but the README explicitly stating "The action should use ERB" is misleading.

Last, I didn't edit this lecture because there are many ways to either hint or out-right say use 'redirect' back to GET '/posts', so I'll leave that you guys. Thanks!

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.