简体   繁体   中英

I can't understand this? (Ruby on Rails)

I'm new to RoR and I am having some trouble understanding some of the code. I tried looking it up but the results haven't helped me.

Here is the code located in the user controller. (If you need any other code, comment it and I'll update

class UsersController < ApplicationController
 def new
  @user = User.new
 end

 def create
   @user = User.new(user_params) #I didn't see any parameters in the constructor
    if @user.save #Checks if @user was saved?
     session[:user_id] = @user.id #Creates a session? What's :user_id and @user_id?
     redirect_to'/' #Redirects to http://localhost:8000/
    else
     redirect_to '/signup' #If all fails go back to signup page
   end
end

private
def user_params
 params.require(:user).permit(:first_name, :last_name, :email, :password)
 end 
end

This is part of a programming course which failed to explain this to me properly. I'm generally aware that this is for a signup form, but I am having trouble comprehending the create and user_params function processes.

When I'm asking for help I am asking you to lead me through the process of what is happening. I also need specific help with params.require(:user).permit(:first_name, :last_name, :email, :password)

@user = User.new(user_params) #I didn't see any parameters in the constructor

user_params is the name of a method. In ruby, you can call a method without writing () after the method name. If you look down at the bottom of the code you posted, you can see the method definition:

private
def user_params
  params.require(:user).permit(:first_name, :last_name, :email, :password)
  end 
end

That method returns something, and that return value is used in the constructor. You can see what the return value is by adding the following to your code:

def create
  @user = User.new(user_params) 
  puts '******'
  p user_params
  puts '******'
  ...
  ...
end

Then look in your server window for the output. You'll see something like:

****** 
{“first_name"=>”Joe”, “last_name”=>”Smith”, “email”=>”joe_smith@yahoo.com”}
*******

params.require has to do with security. The subject is called strong parameters , which you can read about here:

https://www.sitepoint.com/rails-4-quick-look-strong-parameters/

if @user.save #Checks if @user was saved?

Yes:

By default, save always run validations. If any of them fail the action is cancelled and save returns false.

session[:user_id] = @user.id #Creates a session? What's :user_id and @user_id?

A session is used to make variables persist from one request to another. A session is like a Hash, and :user_id is just a random key that you are creating in the Hash. You can name the key anything you want, but it should describe the data that you are saving.

@user.id is the value you are saving in the session Hash. The id comes from the user you created here:

@user = User.new(user_params)

I'm generally aware that this is for a signup form, but I am having trouble comprehending the create and user_params function processes.

First, you use a GET request to display the form for creating a new user--you do that by entering localhost:3000/users/new in your browser. That will display the form. The <form> tag has an action attribute, which specifies the url where the form will send a request accompanied by the data.

If you use your browser's developer tools, you can click on something like Page Source to see the raw html of the form, which will look something like this:

<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post">
...
...

A POST request that is sent to the url /users is routed to the create action in the UsersController. That's because when you declare a route like:

resources :users

or

resources :photos

Rails uses the chart below to route urls to actions (in this case the urls are routed to actions in the PhotosController):

在此处输入图片说明

Note that the url /photos is routed to both the index and the create action. Rails checks whether the request is a GET request or a POST request to determine which action to execute.

For additional information, check out the Rails Guide on routing .

There are two thins going on here. The controller is probably mapped to /users/ path. The controller will direct all POST to create . Similarly, it will direct all GET to index . Which you don't have.

user_params is a function that was created probably as part of your scaffolding. Like rails generate ... In older versions of Rails, it wasn't like this. This allows you to say for the user scope, first_name, last_name, etc are allowed to be submitted via POST. Why is this done? Mostly security. It allows you to whitelisted parameters so that for example user.admin cannot be updated. You can read more about it here .

In your web-app you may want to create and update users' information. For example, in both your views new.html.erb ( which create new user) and edit.html.erb (which update existing user's information), you will probably render a form to let users type their information (with bootstrap).

<div class='row'>
<div class='col-xs-12'>

    <%= form_for(@user, :html => {class: "form-horizontal", role:"form"}) do |f| %>
        <div class="form-group">
            <div class="control-label col-sm-2">
                <%= f.label :first_name,"FName:" %>
            </div>
            <div class="col-sm-8">
                <%= f.text_field :last_name, class: "form-control", placeholder: "Enter username", autofocus: true %>
            </div>


        </div>
        <div class="form-group">
            <div class="control-label col-sm-2">
                <%= f.label :last_name,"LName:" %>
            </div>
            <div class="col-sm-8">
                <%= f.text_field :last_name, class: "form-control", placeholder: "Enter username" %>
            </div>


        </div>
        <br>
        <div class="form-group">
            <div class="control-label col-sm-2">            
                <%= f.label :email, "Email:" %>

            </div>
            <div class="col-sm-8">
                <%= f.email_field :email, class: "form-control", placeholder: "Enter your email" %>
            </div>
        </div>
        <br>
        <div class="form-group">
            <div class="control-label col-sm-2">            
                <%= f.label :password, "Password:" %>

            </div>
            <div class="col-sm-8">
                <%= f.password_field :password, class: "form-control", placeholder: "Enter your password" %>
            </div>
        </div>
        <br>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <%= f.submit(@user.new_record? ? "Sign up now!" : "Update your account", class:'btn btn-primary btn-lg') %>
            </div>
        </div>
    <% end %>
    <div class="col-xs-6 col-xs-offset-3">
        [ <%= link_to 'Cancel request and return to home', root_path %> ]
    </div>

</div>

Back to your question: By doing "params.require(:user).permit(:first_name, :last_name, :email, :password)" will allow the user controller to modify you first_name, last_name, email and password parameter with security.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM