Reputation: 71
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)
Upvotes: 1
Views: 179
Reputation: 48609
@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”=>”[email protected]”}
*******
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.
Upvotes: 3
Reputation: 1
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.
Upvotes: 0
Reputation: 34169
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.
Upvotes: 1