Study Guide for Assessment 4 - Memorizing MVC & Authentication
Assessment 4 - Tuesday, 6/7/16
Essentially, a memorization test where you can't use Google to help you debug, so you'd best memorize all of the possible bugs/solutions you may run into!
Common Errors & Possible Solutions
class User - don't forget these clutch lines
- after_initialize :ensure_session_token - attr_reader :password - @password = password; in def password=(password) method - self.save! in reset_token!
User.new(user_params) in create method (not find(params[:id])
before_filter :require_logged_in - at top of LinksController
The following error message means you likely either wrote link_url when you should have written links_url, or forgot to pass in @link or link_id into link_url(@link)
“No route matches {:action=>”show”, :controller=>”links”} missing required keys: [:id]
Since link_url requires an :id or @link, get “missing required keys: [:id]” error message
`` - only put at bottom of all pages (application.html.erb), in if/else logged_in? block. If you put it in individual pages as well as application.html.erb, Capybara will get confused and won't know which of the two buttons to press
save_and_open_page - put line in rspec, and Capybara will pop open the page in your browser.
Useful for seeing what Capybara is seeing
Can tell you when Capybara is ending up at the wrong page, so you need to fix a link (rather than checking an html.erb page)
If redirecting to wrong page, check action=“” is directing to correct url (especially since copying & pasting)
rails g model User username:string password_digest:string session_token:string
Will create both Migration file & Model file at the same time
Migration file with have column names pre-written, just have to add null: false, indexes, and unique: true constraints
rails g controller Link new create index show update destroy
Will create all controller actions & routes that you list, when creating Controller
Don't have to write def create / end for all of the different methods, faster
Flash.now[:errors] - only sets the lifecycle of an error message, but can still print them by iterating through flash[:errors]
Safer to just use flash[:errors] on this assessment, less likely to run into bugs
In general, should prioritize flash.now so errors don't persist needlessly
rails d controller “NameController” - delete controller & all associated files
Delete controller & associated files - in case you made a mistake
resource :session - in routes.rb, both "resource" and "session" should be singular
Capybara:ElementNotFound - most likely means Capybara is ending up in the wrong place, check destination_url of button/link you’re coming from
The following error crops up a lot:
Failure/Error: expect(response).to render_template("new") expecting but rendering with ActionView::Template::Error: No route matches {:action=>"show", :controller=>"links"} missing required keys: [:id]
My solution was to fix the destination_url in the button that was pointing to this view
<%= button_to "Sign Out", session_url, method: :delete %>
Not sure if this solves all circumstances
Unable to find field “URL"
Make sure input is labelled id="URL" since Capybara uses the id tag to change/update fields
Capybara is case sensitive
The following error may indicate that you swapped the order of require/permit in your strong_params
Failure/Error: click_button 'Add Comment' ArgumentError: wrong number of arguments (3 for 1)
Issue: params.permit(:comment).require(:body, :link_id, :user_id)
Correct code: params.require(:comment).permit(:body, :link_id, :user_id)
The following error cropped up when I was pre-filling value="" in session/new.html.erb
Failure/Error: click_button "Sign In" ActionView::Template::Error: undefined method `username' for nil:NilClass
The code worked when I removed the pre-filled in value, so a/A was not checking for the username to persist if user entered it incorrectly the first time
Another solution is to pass in @user = User.new({username: params[:user][:username]}) in the Session Controller's create method, in case they want incorrect username/passwords to persist
application_controller.rb - Application Controller
user_controller.rb - User Controller
session_controller.rb - Session Controller
new.html.erb - New User Form, can reference HTML code for other forms
The rest can be logic-ed through and pieced together from there, based on the project & specs
Incorrectly had before_action :require_logged_in in SessionController rather than LinksController
Failure/Error: post :create, user: {username: "jill_bruce", password: "abcdef"} RuntimeError: @controller is nil: make sure you set it in your test's setup method.
This errors also crops up when you mis-name the SessionsController as SessionController (singular). Must rename all controller & view files
Must pass in username as a hash in create action of session_controller.rb
Failure/Error: post :create, user: {username: "jack_bruce", password: "notmypassword"} ArgumentError: When assigning attributes, you must pass a hash as an argument.
@user = User.new({username: params[:user][:username]})
Use this line to guarantee that we can pre-fill username, but must be passed into User.new as a hash and not just a value
This error crops up when you forget to include the erb tag in action="___"
Failure/Error: sign_in('jack_bruce') ActionController::RoutingError: No route matches [POST] "/session/session_url"
Incorrect: action="session_url"
The following crops up when you forget to pass @link to edit_link_url(@link)
Failure/Error: sign_up_as_ginger_baker ActionView::Template::Error: No route matches {:action=>"edit", :controller=>"links"} missing required keys: [:id]
"missing required keys: [:id]" generally means that you forgot to pass an id/object to the route_url
Don't forget that edit_*_url requires a specific object to edit!
Failure/Error: click_button 'Add Comment' ActiveRecord::RecordNotFound: Couldn't find Link with 'id'=
Can't quite remember the original problematic code, but the correct version is:
Add Comment " method="post" >
Redirect to new_session_url, not links_url
Another possible reason your errors may not be rendering (besides not recording them in flash[:errors] or not printing them in the view, is that you may not be validating the presence of those characteristics.
Failure/Error: expect(page).to have_content "Body can't be blank" expected to find text "Body can't be blank" in "Links google http://google.com Edit Link Add Comment ginger_baker"
Solution: validates :body, presence: true
Need to use redirect_to when adding a comment nested in the links show page, even when comment is not valid. Cannot just render link_url(@link)
Failure/Error: click_button 'Add Comment' ActionView::MissingTemplate: Missing template http://www.example.com/links/1 with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby]}. Searched in: * "/Users/joy/AA_CodePractice/AppAcademy/Assessment4/a4-practice4/app/views"
if @comment.save redirect_to link_url(@link) else flash[:errors] = @comment.errors.full_messages redirect_to link_url(@link) # render link_url(@link) end