[RUBY] Rails Tutorial 6th Edition Learning Summary Chapter 10

Overview

This article deepens my understanding by writing a Rails tutorial commentary article to further solidify my knowledge It is part of my study. In rare cases, ridiculous content or incorrect content may be written. Please note. I would appreciate it if you could tell me implicitly ...

Source Rails Tutorial 6th Edition

What to do in this chapter

Since we were able to implement user creation, login, and memory of login information Next, create update, display, and delete functions that were left unattended in user resources.

Update user

Edit the edit action to update the user. The new actions of the sessions controller that we have implemented so far Prepare a form like the new action of the Users controller and You can implement the operation of sending the input value of the form to the update action. Of course, the user can edit it, but using the authentication implemented so far We will implement access control.

Edit form

The edit page contains the target user's ID in the URL ex) users/1/edit

Use this to extract the user from the URL ID and save it in an instance variable.

  def edit
    @user = User.find(id: params[:id])
  end

By doing this, specify the `` `@ user``` object as the model object in the form to be created next.

erb:edit.html.erb


<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_with(model: @user, local: true) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="https://gravatar.com/emails" target="_blank">change</a>
    </div>
  </div>
</div>

Reusing the _error_messages partial to display an error message when entering an invalid value in a form.

Also, there is `` `target =" _ blank "``` in the link part of gravatar, but by writing like this, you can display the link destination in a new tab.

In addition, the value currently contained in the @user variable is automatically entered in the input field of the form. It seems that Rails will pull the attribute information automatically saved and display it. Guu competent.

Except for the actual HTML generated from this erb <input type="hidden" name="_method" value="patch"> There is such a description. Rails can't send a PATCH request, which is an update request, because the web browser can't send it. By specifying patch in the hidden input field, it is forged as a pseudo PATCH request.

Another thing to keep in mind is that the new and edit actions use almost the same erb code Why Rails can tell if it's a new user or an existing user This is because ActiveRecord's `new_record?` Method can be used to determine whether it is new or existing.

>> new_user = User.new
   (1.3ms)  SELECT sqlite_version(*)
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil, remember_digest: nil>
>> user1 = User.first
  User Load (0.6ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "take", email: "[email protected]", created_at: "2020-06-14 02:57:10", updated_at: "2020-06-20 03:53:57", password_digest: [FILTERED], remember_digest: "$2a$12$tYO.HIfYezXpTk2zRp9s6uqJY4wUkPM28NfYuJ7vxq/...">
>> new_user.new_record?
=> true
>> user1.new_record?
=> false
>> 

In the actual erbform_For model objects when using withnew_record?```Look at the result of Determine if it is post or patch.

Finally, set a link to the edit action in the navigation bar. <li><%= link_to "settings", edit_user_path(current_user) %></li>

#####Exercise 1.I was curious, so as a result of investigating what kind of vulnerabilities there are, the following article was helpful, so I will leave it. https://webegins.com/target-blank/ "noopener"Super important!

2.The form part is almost the same in the new view and the edit view. It's about the text of the submit button. Therefore, use the provide method to change the text content of the submit button. Partially refactor together.

erbb:_form.html.erb


    <%= form_with(model: @user, local: true) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit yield(:btn_text), class: "btn btn-primary" %>
    <% end %>

erb:new.html.erb


<% provide(:title, 'Sign up') %>
<% provide(:btn_text, "Create my account") %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
  </div>
</div>

erb:edit.html.erb


<% provide(:title, "Edit user") %>
<% provide(:btn_text, "Save changes") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="https://gravatar.com/emails" target="_blank" rel="noopener">change</a>
    </div>
  </div>
</div>

####Editing failure As with user registration, we will implement it regarding editing failures when trying to update with an invalid value. We will implement the update action, but it is the same as creating a user using params with the create action. Update using the params sent from the edit action. The structure is quite similar. Of course, it is dangerous to update the DB directly with params, so this time also StrongParameter(Previously defined user_params method)use.

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      
    else
      render 'edit'
    end
  end

At the moment with User model validation_error_messages Because there is a partial It is designed to return an error for invalid values.

#####Exercise 1.Fail. image.png

####Test when editing fails Create user editing-related integration tests. This time, as the title suggests, I will write a test when editing fails. rails g integration_test user_edit

users_edit_test.rb


require 'test_helper'

class UserEditTest < ActionDispatch::IntegrationTest
  def setup 
    @user = users(:michael)
  end
  
  test "unsuccessful edit" do
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user) , params:{user:{name: "",
                                           email: "foo@bar",
                                           password: "foo",
                                           password_confirmation: "bar"}}
    assert_template 'users/edit'
  end
end

1.GET request on edit page, check if edit page is drawn 2.Send patch request, invalid value to update action 3.Check if the edit page is redrawn.

It becomes a test in the order of.

#####Exercise 1. assert_select 'div.alert', "The form contains 4 errors."

####Successful editing with TDD This time, we will implement the operation at the time of success. User⁻ The image is already working because it is implemented in Gravatar. name,email,Implement successful editing of other attributes such as password.

A test to write an integration test before implementing a feature and determine if the feature is acceptable when the feature has been implemented Is called an "acceptance test". Let's actually implement successful editing with TDD.

It is easy to understand if you implement it by referring to the test at the time of failure that you implemented earlier.(Of course we will send valid data)

  test "successful edit" do
    get edit_user_path(@user)
    assert_template 'users/edit'
    name = "foo"
    email = "[email protected]"
    patch user_path(@user) , params:{user:{name: name,
                                           email: email,
                                           password: "",
                                           password_confirmation: ""}}
    
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

Deepen your understanding by writing Rails tutorial commentary articles to make sure It is part of my study. In rare cases, ridiculous content or incorrect content may be written. Please note. I would appreciate it if you could tell me implicitly ...

Source Rails Tutorial 6th Edition

###What to do in this chapter Since we were able to implement user creation, login, and memory of login information Next, create update, display, and delete functions that were left unattended in user resources.

###Update user Edit the edit action to update the user. The new actions of the sessions controller that we have implemented so far Prepare a form like the new action of the Users controller and You can implement the operation of sending the input value of the form to the update action. Of course, the user can edit it, but using the authentication implemented so far We will implement access control.

####Edit form The edit page contains the target user's ID in the URL ex) users/1/edit

Use this to extract the user from the URL ID and save it in an instance variable.

  def edit
    @user = User.find(id: params[:id])
  end

By doing this, the next form you will create will be a model object.@userSpecify the object.

erb:edit.html.erb


<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
     <%= form_with(model: @user, local: true) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="https://gravatar.com/emails" target="_blank">change</a>
    </div>
  </div>
</div>

To display an error message when entering an invalid value in the form_error_messages Reusing partials.

Also at the link part of gravatartarget="_blank"However, by writing like this, the link destination can be displayed in a new tab.

Furthermore, in the input field of the form@The value currently contained in the user variable is automatically entered. It seems that Rails will pull the attribute information automatically saved and display it. Guu competent.

Except for the actual HTML generated from this erb <input type="hidden" name="_method" value="patch"> There is such a description. Rails can't send a PATCH request, which is an update request, because the web browser can't send it. By specifying patch in the hidden input field, it is forged as a pseudo PATCH request.

Another thing to keep in mind is that the new and edit actions use almost the same erb code Why Rails can tell if it's a new user or an existing user ActiveRecordnew_record?This is because the method can determine whether it is new or existing.

>> new_user = User.new
   (1.3ms)  SELECT sqlite_version(*)
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil, remember_digest: nil>
>> user1 = User.first
  User Load (0.6ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> #<User id: 1, name: "take", email: "[email protected]", created_at: "2020-06-14 02:57:10", updated_at: "2020-06-20 03:53:57", password_digest: [FILTERED], remember_digest: "$2a$12$tYO.HIfYezXpTk2zRp9s6uqJY4wUkPM28NfYuJ7vxq/...">
>> new_user.new_record?
=> true
>> user1.new_record?
=> false
>> 

In the actual erb, when using ``` form_with, see the result of new_record?` `` For the model object. Determine if it is post or patch.

Finally, set a link to the edit action in the navigation bar. <li><%= link_to "settings", edit_user_path(current_user) %></li>

Exercise
  1. I was curious, so as a result of investigating what kind of vulnerabilities there are, the following article was helpful, so I will leave it. https://webegins.com/target-blank/ "noopener" super important!

  2. The form part is almost the same in the new view and the edit view. It's about the text of the submit button. Therefore, use the provide method to change the text content of the submit button. Partially refactor together.

erbb:_form.html.erb


   <%= form_with(model: @user, local: true) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.label :password_confirmation, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit yield(:btn_text), class: "btn btn-primary" %>
    <% end %>

erb:new.html.erb


<% provide(:title, 'Sign up') %>
<% provide(:btn_text, "Create my account") %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
  </div>
</div>

erb:edit.html.erb


<% provide(:title, "Edit user") %>
<% provide(:btn_text, "Save changes") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="https://gravatar.com/emails" target="_blank" rel="noopener">change</a>
    </div>
  </div>
</div>

Editing failure

As with user registration, we will implement it regarding editing failures when trying to update with an invalid value. We will implement the update action, but it is the same as creating a user using params with the create action. Update using the params sent from the edit action. The structure is quite similar. Of course, it is dangerous to update the DB directly with params, so we will use StrongParameter (previously defined user_params method) this time as well.

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      
    else
      render 'edit'
    end
  end

Because there is a User model validation and a _error_messages partial at this time It is designed to return an error for invalid values.

Exercise
  1. Fail. image.png

Test when editing fails

Create user editing-related integration tests. This time, as the title suggests, I will write a test when editing fails. rails g integration_test user_edit

users_edit_test.rb


require 'test_helper'

class UserEditTest < ActionDispatch::IntegrationTest
  def setup 
    @user = users(:michael)
  end
  
  test "unsuccessful edit" do
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user) , params:{user:{name: "",
                                           email: "foo@bar",
                                           password: "foo",
                                           password_confirmation: "bar"}}
    assert_template 'users/edit'
  end
end
  1. GET request on edit page, check if edit page is drawn
  2. Send patch request, invalid value to update action
  3. Check if the edit page is redrawn.

It becomes a test in the order of.

Exercise

1. assert_select 'div.alert', "The form contains 4 errors."

Successful editing with TDD

This time, we will implement the operation at the time of success. User⁻ The image is already working because it is implemented in Gravatar. Implement successful editing of other attributes such as name, email, password.

A test to write an integration test before implementing a feature and determine if the feature is acceptable when the feature has been implemented Is called an "acceptance test". Let's actually implement successful editing with TDD.

It will be easier to understand if you implement it by referring to the test at the time of failure that you implemented earlier. (Of course I will send valid data)

  test "successful edit" do
    get edit_user_path(@user)
    assert_template 'users/edit'
    name = "foo"
    email = "[email protected]"
    patch user_path(@user) , params:{user:{name: name,
                                           email: email,
                                           password: "",
                                           password_confirmation: ""}}
    
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

Of course the test fails. First, it doesn't implement flash messages. You have not specified a redirect. These two get caught. And the most important part. Since the password value is empty, validation is caught and it cannot be updated normally.

The former two are implemented on this line.

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    
    end
  end

At this point, @ user.update has a blank password and is caught in validation and branches to an else statement. The test doesn't work either. As a countermeasure, add exception handling when the password is empty. In such a case, it is convenient to use the option allow_nil: true. With this, even if it is blank, it will not be caught in validation. This option passes the existence verification, but when the object is created on the `` `has_secure_passwordmethod side Since the validation of existence works, nil is repelled when creating a new one, and if it is nil when updating, the password is not changed. The operation can be realized. In addition, the validation defined in the model by adding thisallow_nil: trueoptionhas_secure_password```It also solves the problem that the same error message is displayed due to duplicate method validation.

Exercise
  1. Succeed image.png

  2. The default Gravatar image is displayed instead. image.png

Authorization

Authentication in a web application identifies the user. Authorization is to manage the range of operations that can be performed by the user. The update and edit actions that have been implemented so far have major flaws, In the current state, all users can be edited regardless of which user is logged in. The Setting link in the navigation bar takes you to the edit page of the logged-in user If you specify the edit action of various users directly in the URL, you can access it and update it.

This is bad, so change the behavior to the correct one. In particular If you are not logged in, forward to the login page + message is displayed. If you are logged in but are trying to access another user, forward to the root URL.

Ask user to log in

Before the edit, update action is executed using the before filter in the Users controller Be sure to implement to force login.

  before_action :logged_in_user, only:[:edit,update]
  .
  .
  .
    def logged_in_user
      unless logged_in?
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

By implementing in this way, the logged_in_user method is always executed before executing the edit and update actions. When you are not logged in, a flash message prompts you to log in. Redirect to the login page.

And at this stage, if you access the edit view without logging in, you will be taken to the login page. The test fails because it is now skipped.

In user_edit_test.rb, log in before accessing the edit action so that the test will pass. Use the log_in_as method because it is defined for testing.

The test will now pass. However, commenting out the before_action line does not reject the test. This is a serious security hole and it's bad if it doesn't get hit in the test I will fix it so that it will repel in the test firmly.

  test "should redirect edit when not logged in" do
    get edit_user_path(@user)
    assert_not flash.empty?
    assert_redirected_to login_path
  end
  
  test "should redirect update when not logged in" do
    patch user_path(@user), params:{ user: {name: @user.name,  
                                            email: @user.email }}
    assert_not flash.empty?
    assert_redirected_to login_path
  end 

By adding tests like this To always test if log_in_user is running before executing the edit, update actions It will open security holes in tests.

Exercise
  1. The new page and signup action cannot be executed and an error occurs.
 FAIL["test_should_get_new", #<Minitest::Reporters::Suite:0x00007f1d1cf4dab8 @name="UsersControllerTest">, 0.06502773099964543]
 test_should_get_new#UsersControllerTest (0.07s)
        Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/login>
        Response body: <html><body>You are being <a href="http://www.example.com/login">redirected</a>.</body></html>
        test/controllers/users_controller_test.rb:10:in `block in <class:UsersControllerTest>'

 FAIL["test_invalid_signup_information", #<Minitest::Reporters::Suite:0x00007f1d1cff74c8 @name="UsersSignupTest">, 0.08553676799965615]
 test_invalid_signup_information#UsersSignupTest (0.09s)
        expecting <"users/new"> but rendering with <[]>
        test/integration/users_signup_test.rb:12:in `block in <class:UsersSignupTest>'

 FAIL["test_valid_signup_information", #<Minitest::Reporters::Suite:0x00007f1d1d0494d0 @name="UsersSignupTest">, 0.09624041300003228]
 test_valid_signup_information#UsersSignupTest (0.10s)
        "User.count" didn't change by 1.
        Expected: 2
          Actual: 1
        test/integration/users_signup_test.rb:20:in `block in <class:UsersSignupTest>'

  9/9: [================================================================] 100% Time: 00:00:01, Time: 00:00:01

Request the right user

Next, even if you are logged in, you will not be able to edit unless you are the person. We will proceed with TDD.

First, add a second user to fixture to create a situation where you log in as another user.

users.yml


archer: 
  name: Sterling Archer
  email: [email protected]
  password_digest: <%= User.digest('password') %>

Then log in as @other_user in the test and Write a test to update @user.

  test "should redirect edit when logged in as wrong user" do
    log_in_as(@other_user)
    get edit_user_path(@user)
    assert flash.empty?
    assert_redirected_to root_path
  end
  
  test "should redirect update when logged in as wrong user" do
    log_in_as(@other_user)
    patch user_path(@user), params:{ user: { name: @user.name,
                                             email: @user.email}}
    assert flash.empty?
    assert_redirected_to root_path
  end

This is a test because the flash message is not displayed and is just skipped to the root URL.

I write a test and of course it doesn't pass Write the code to pass the test.

Specifically, if you create a correct_user method and there is no user before executing the edit, update action Write the process to skip to the root URL.

users_controller.rb


  before_action :correct_user, only:[:edit,:update]
    


  private
    def correct_user
      @user = User.find(params[:id])
      redirect_to root_url unless @user == current_user
    end

The test will now pass.

Finally, define the `current_user? ``` method and incorporate it into the `correct_user``` method you defined earlier.

    def correct_user
      @user = User.find(params[:id])
      redirect_to root_url unless current_user?(@user)
    end
  def current_user?(user)
    user && user == current_user
  end
Exercise
  1. If you did not protect the update action, directly with the curl command etc. without going through the edit action (edit page) If you send a value, you can update it.

  2. The edit action is easier to test. (Actually log in and display the edit path of another user)

Friendly forwarding

It also makes this update feature useful. In particular logged_in_userWhen the method repels access to the edit page of an unlogged-in user and jumps to the login page If you log in as it is, you will be skipped to the user details page (show) without asking questions, It's a bit inconvenient to see the show page when I log in to access the edit page. Improve this so that when you log in, you will be taken to the edit page (friendly forwarding)

Since the test can be implemented like this Check to access the edit page without logging in and redirect to the edit page after logging in.

test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_redirected_to edit_user_url(@user)
    name = "foo"
    email = "[email protected]"
    patch user_path(@user) , params:{user:{name: name,
                                           email: email,
                                           password: "",
                                           password_confirmation: ""}}
    
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

Now that I've written a test that fails at this point, I'll write the code so that this test passes. Write a process to save the page at the time of request and redirect to it at login.

Define a method in sessions_helper.

sessions_helper.rb


  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end
  
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
  end

store_locationThen I am writing a process to save the URL of the request destination in a temporary session. At this time, I have to save only the GET request

In the unlikely event that you log in to access the form page and delete the intentionally saved login information cookies When I submit the contents of the form, URLs such as post and patch are saved. If you use the `` `redirect_back_or``` method in that state, a GET request will be sent to the URL that expects post, patch, etc. by redirect. It will be sent and there is a high possibility that an error will occur. You can avoid these risks by focusing on GET requests.

logged_in_userTo the methodstore_locationPut the method, save the request destination url, By putting the `redirect_back_or method` in the create action of sessions_controller At login, if there is a URL saved in the session, redirect to it.

sessions_controller.rb


  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user&.authenticate(params[:session][:password])
      log_in(@user)
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      redirect_back_or @user
    else
      flash.now[:danger] = "Invalid email/password combination"
      render 'new'
    end
  end

users_controller.rb


    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

By the way, unless there is a return or a direct call to the last line of the method The redirect is done at the end of the method.

The test passes with the above contents.

Exercise
  1. Make sure that the saved URL disappears when you log in and redirect to the edit page.

user_edit_test.rb


  test "successful edit with friendly forwarding" do
    get edit_user_path(@user)
    log_in_as(@user)
    assert_nil session[:forwarding_url] #Add here
    assert_redirected_to edit_user_url(@user)
    name = "foo"
    email = "[email protected]"
    patch user_path(@user) , params:{user:{name: name,
                                           email: email,
                                           password: "",
                                           password_confirmation: ""}}
    
    assert_not flash.empty?
    assert_redirected_to @user
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end
(byebug) session[:forwarding_url]
"https://12b7e3b6aec94b45960b81560e233372.vfs.cloud9.us-east-2.amazonaws.com/users/1/edit"
(byebug) request.get?
true

Finally

I've been doing more and more at the end of the chapter I will summarize it for the time being.

rails t
git add -A
git commit -m "Finish user edit, update, index and destroy actions"
git co master
git merge updating-users
git push
rails t 
git push heroku
heroku pg:reset DATABASE
heroku run rails db:migrate
heroku run rails db:seed

The production DB is `pg: reset DATABASE`. In addition, the application name that resets the DB to prevent mistakes You will be asked to enter it, so enter it and reset Or with the --confirm option

reset DATABASE -c App name


 You can do it.

 After that, migrate and add samples on heroku and finish.


 [To the previous chapter](https://qiita.com/take_webengineer/items/48bb1a43ffac4290959f)

 [To the next chapter]()


Recommended Posts

Rails Tutorial 6th Edition Learning Summary Chapter 10
Rails Tutorial 6th Edition Learning Summary Chapter 7
Rails Tutorial 6th Edition Learning Summary Chapter 4
Rails Tutorial 6th Edition Learning Summary Chapter 9
Rails Tutorial 6th Edition Learning Summary Chapter 6
Rails Tutorial 6th Edition Learning Summary Chapter 5
Rails Tutorial 6th Edition Learning Summary Chapter 2
Rails Tutorial 6th Edition Learning Summary Chapter 3
Rails Tutorial 6th Edition Learning Summary Chapter 8
Rails Tutorial (4th Edition) Summary
Rails Tutorial (4th Edition) Memo Chapter 6
Rails Tutorial Chapter 3 Learning
Rails Tutorial Chapter 4 Learning
Rails Tutorial Chapter 1 Learning
Rails Tutorial Chapter 2 Learning
Rails Tutorial 4th Edition: Chapter 1 From Zero to Deployment
[Rails Struggle/Rails Tutorial] Summary of Rails Tutorial Chapter 2
rails tutorial chapter 10 summary (for self-learning)
rails tutorial Chapter 6
rails tutorial Chapter 1
rails tutorial Chapter 7
rails tutorial Chapter 5
rails tutorial Chapter 10
rails tutorial Chapter 9
rails tutorial Chapter 8
Rails Tutorial Chapter 0: Preliminary Basic Knowledge Learning 5
Rails tutorial (6th edition) Follow/unfollow background operation
Rails Tutorial Chapter 5 Notes
Rails Tutorial Chapter 10 Notes
Rails Tutorial Chapter 3 Notes
[Rails] Learning with Rails tutorial
Rails Tutorial Memorandum (Chapter 3, 3.1)
Rails Tutorial Chapter 4 Notes
Rails Tutorial Chapter 8 Notes
Rails Tutorial Memorandum (Chapter 3, 3.3.2)
Rails tutorial (6th edition) Background operation of profile editing
[Rails Tutorial Chapter 4] Rails-flavored Ruby
Rails tutorial (6th edition) Background operation of login function
Rails tutorial (6th edition) Background operation of password reset function
[Rails Tutorial Chapter 5] Create a layout
Chewing Rails Tutorial [Chapter 2 Toy Application]
rails tutorial
rails tutorial
rails tutorial
rails tutorial
Rails Tutorial (6th Edition) -Explanation of background operation for each function-
rails tutorial
rails tutorial
rails tutorial
[Rails Struggle/Rails Tutorial] Summary of Heroku commands
Rails tutorial (6th edition) Background operation of the posting function of the micro post
A summary of only Rails tutorial setup related
[Rails Struggle/Rails Tutorial] What you learned in Rails Tutorial Chapter 6
Rails tutorial test
[Rails Struggle/Rails Tutorial] What you learned in Rails Tutorial Chapter 3
[Ruby on Rails] Rails tutorial Chapter 14 Summary of how to implement the status feed
Rails tutorial memorandum 1
Rails Tutorial Chapter 1 From Zero to Deployment [Try]
Rails learning day 3
Rails tutorial memorandum 2
Rails learning day 4