简体   繁体   English

Rails RESTful控制器操作来创建用户

[英]Rails RESTful controller action to create User

I am re-reading railstutorial the second time for clarity. 为了清楚起见,我第二次重读了Railstutorial I was trying to understand RESTful resources provided by rails where it listed various HTTP request with corresponding controller actions: index, show, new, create, edit, update, destroy. 我试图了解rails提供的RESTful资源 ,其中列出了各种HTTP请求以及相应的控制器操作: 索引,显示,新建,创建,编辑,更新,销毁。

I never really fully understood how rails controller works and I wanted to clarify it. 我从来没有真正完全理解过Rails控制器的工作原理,我想澄清一下。 If I make a users_controller.rb and want to create new user, and that's it . 如果我创建一个users_controller.rb并想要创建新用户, 就是这样 I don't care about redirecting, flash messages, and other flairs. 我不在乎重定向,即时消息和其他风格。 I just want to create new user and save it on my database. 我只想创建一个新用户并将其保存在我的数据库中。

I want to do User.create(name: "Iggy1", email: "letsmail@iggy.com") . 我想做User.create(name: "Iggy1", email: "letsmail@iggy.com") Assume I did migration and I have name (string) and email (string) on DB schema. 假设我进行了迁移,并且在数据库架构上有name (字符串)和email (字符串)。

What is the least code line on users_controller.rb needed to create a user? 创建用户所需的users_controller.rb上最少的代码行是什么?

The reason why I ask this question is up til now, I am still not 100% sure which code line actually performs the desired action. 直到现在我提出这个问题的原因,我仍然不确定100%哪个代码行实际执行了所需的操作。 Is rails actually smart enough to recognize these specific keywords index , new , create , destroy , show , edit , and update , or are they arbitrary? Rails实际上足够聪明,可以识别这些特定的关键字indexnewcreatedestroyshoweditupdate ,或者它们是任意的吗? If rails is smart enough to detect those seven keywords, by merely listing the method ( def destroy; #<no code>; end ), is DELETE user method automatically accessible, or I have to actually say def destroy; User.find(params[:id]).destroy; end 如果rails足够聪明以检测这七个关键字,只需列出方法( def destroy; #<no code>; end ),是否可以自动访问DELETE用户方法,或者我必须说def destroy; User.find(params[:id]).destroy; end def destroy; User.find(params[:id]).destroy; end def destroy; User.find(params[:id]).destroy; end to use DELETE user method? def destroy; User.find(params[:id]).destroy; end使用DELETE用户方法? On users_controller.rb , I have, from railstutorial, in the end, this elaborate code. users_controller.rb ,我有,从railstutorial,最终,这出精心设计的代码。

...
  def create
    @user = User.new(user_params)
    if @user.save
      @user.send_activation_email
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new'
    end
  end
...

Is merely having def create on Users_controller sufficient for rails to create a user? 仅在Users_controller上def create就足以使Rails创建用户吗?

def create
end

Or I need at least to have User.new , or more codes to create new user? 还是我至少需要User.new或更多代码才能创建新用户?

The first thing you'll need to create a user is a 'new' action in your UsersController, like the following: 创建用户的第一件事是在UsersController中执行“新”操作,如下所示:

class UsersController < ApplicationController

  def new
      @user = User.new
  end

end

When you declare the above method definition, Rails will expect a file named 'new.html.erb', unless you tell it to render another template. 当您声明上述方法定义时,Rails将期望一个名为“ new.html.erb”的文件,除非您告诉它呈现另一个模板。

NOTE: I'll continue under the assumption that you don't want to do this, but if you did, you would add render 'other' to the end of your 'new' method (where 'other' is the file 'other.html.erb'): 注意:我将假设您不想这样做,但是如果您这样做了,则可以在“ new”方法的末尾添加render 'other' (其中“ other”是文件“ other”) .html.erb'):

Since your goal is to create a new User instance, this view template will need a form to add the name and email fields. 由于您的目标是创建一个新的User实例,因此该视图模板将需要一个表单来添加名称和电子邮件字段。 While not required for all Rails forms, one common way of creating a User is to create a 'new' (ie unsaved) User instance and pass it to the form, so that the form knows which attributes a User has. 尽管并非所有Rails表单都需要,但创建User的一种常用方法是创建一个“新”(即未保存)的User实例,并将其传递给表单,以便表单知道User拥有哪些属性。 Rails passes this instance variable to the view, and it also knows which view file to render (because the 'new' method you defined should be named the same thing as the 'new.html.erb' view template that contains the form). Rails将此实例变量传递给视图,并且它也知道要呈现的视图文件(因为您定义的“ new”方法应与包含表单的“ new.html.erb”视图模板命名为同一名称)。 This is also how Rails knows that the 'submit' button of the form should read 'Create user'. 这也是Rails知道表单的“提交”按钮应显示为“创建用户”的方式。

Assuming you have the above, the next step is adding a place for the form data to be sent once you click the form's "Submit" button. 假设您已经具备上述条件,那么下一步就是添加一个位置,以供您在单击表单的“提交”按钮后发送表单数据。 This is what the 'create' action does. 这就是“创建”操作的作用。 In other words, the 'new' action is in charge of displaying the form in your browser, and the 'create' action is in charge of handling the data submitted by that form. 换句话说,“新”操作负责在浏览器中显示表单,“创建”操作负责处理该表单提交的数据。 The bare minimum code you'll need to add at this point is the following: 此时,您需要添加的最低代码如下:

def create
  @user = User.create(user_params)
end

The way Rails does this is through a special method it implements, called 'params'. Rails的实现方式是通过它实现的一种特殊方法,称为“参数”。 Behind the scenes, Rails takes the HTTP request that occurs when you submit the form, and stores certain data in an ActionController::Parameters object. 在后台,Rails接收提交表单时发生的HTTP请求,并将某些数据存储在ActionController :: Parameters对象中。 This data is then processed by the 'user_params' method (which you'll need to declare; see below), and only the paramaters which you whitelist in that method definition (ie 'name' and 'email') are returned. 然后,这些数据由“ user_params”方法(您需要声明;请参见下文)处理,并且仅返回在该方法定义中白名单的参数(即“ name”和“ email”)。

This implies that you'll need to implement that 'user_params' method definition. 这意味着您需要实现该“ user_params”方法定义。 This is typically done as a private method at the bottom of your UsersController, since you don't want this method available outside of the controller. 通常,这是在UsersController底部作为私有方法完成的,因为您不希望在控制器外部使用此方法。 So you'd add the following: 因此,您需要添加以下内容:

private

def user_params
  params.require(:user).permit(:name, :email)
end

This is important from a security standpoint because a malicious user could potentially add new form elements in their browser (for instance, an element named 'admin') and click 'submit'. 从安全角度来看,这很重要,因为恶意用户可能会在其浏览器中添加新的表单元素(例如,名为“ admin”的元素)并单击“提交”。 If your User model does indeed include an 'admin' attribute, that malicious user has just created an Admin user (with corresponding Admin privileges). 如果您的用户模型确实包含“ admin”属性,则该恶意用户刚刚创建了一个Admin用户(具有相应的Admin特权)。

Finally, since the request that the form sends is a POST request (not a get request), Rails expects you to provide a view to send the user to after they submit the form. 最后,由于表单发送的请求是POST请求(而不是get请求),因此Rails希望您提供一个视图,以在用户提交表单后将其发送给该用户。 This view is typically the 'show.html.erb' template for the user you've just created, since the 'create' doesn't have a template of its own (remember, the form we've discussed is the view for the 'edit' action, not the 'create' action). 该视图通常是您刚刚创建的用户的“ show.html.erb”模板,因为“创建”没有自己的模板(请记住,我们讨论过的表单是该视图的“编辑”操作,而不是“创建”操作)。 The 'show' view is rendered by the following method: “显示”视图通过以下方法呈现:

def show
end

In addition, you'll need to tell Rails to redirect to the 'show' page after the 'create' action is finished. 另外,您需要在完成“创建”操作后告诉Rails重定向到“显示”页面。 Add this to the end of your 'create' method: 将其添加到“ create”方法的末尾:

  redirect_to @user

Since you passed a single instance of the User class, Rails infers that you want to redirect to the 'show' action (as opposed to 'index' or some other action) of the User controller. 由于您传递了User类的单个实例,Rails推断您要重定向到User控制器的“ show”操作(与“ index”或其他操作相反)。 Depending on what you pass to the "redirect_to" method, you can send your user to any number of destinations. 根据传递给“ redirect_to”方法的内容,可以将用户发送到任意数量的目的地。 See these docs for more info. 有关更多信息,请参见这些文档

So in summary, besides the 'edit.html.erb' and 'show.html.erb' view templates and the route declaration in your 'config/routes.rb' file (which I haven't discussed in detail, since the question scope is limited to the UsersController), the bare minimum amount of code your UsersController should have is the following: 因此,总而言之,除了“ edit.html.erb”和“ show.html.erb”视图模板以及“ config / routes.rb”文件中的路由声明(由于问题,我没有详细讨论)。范围仅限于UsersController),UsersController应该拥有的最少代码如下:

class UsersController < ApplicationController

    def new
        @user = User.new
    end

    def create
        @user = User.create(user_params)
        redirect_to @user
    end

    def show
    end

    private

    def user_params
        params.require(:user).permit(:name, :email)
    end
end

You have to understand rails is built on MVC and REST. 您必须了解Rails是基于MVC和REST构建的。 MVC is an architectural pattern to distribute responsibility of your project. MVC是一种架构模式,用于分配项目责任。

M - Model, which interacts with the database and the ideal place to implement business logic. M-模型,与数据库以及实现业务逻辑的理想场所进行交互。

V - View, where the HTML rendering happens V-视图,HTML渲染发生的位置

C - Controller, basically bridges the communication between M and V. C-控制器,基本上桥接了M和V之间的通信。

So, basically when the end user accesses your domain the request comes to the webserver and then, to the rails API. 因此,基本上,当最终用户访问您的域时,请求首先到达Web服务器,然后到达Rails API。 The rails API would know the default controller to transfer the request and the default controller action would return the html output. Rails API将知道默认控制器来传输请求,并且默认控制器操作将返回html输出。

Default router in config/routes.rb config / routes.rb中的默认路由器

root to: 'controller#action'

Likewise rails understands the 5 HTML methods which are GET, POST, PUT, DELETE and PATCH. 同样,Rails理解5种HTML方法,即GET,POST,PUT,DELETE和PATCH。 So, once you create a controller and set the reference in routes.rb as resources [controller_name] then, the rails routes would create 8 urls for each of the 8 default actions in your controller. 因此,一旦创建了一个控制器并将在route.rb中的引用设置为resources [controller_name] ,那么rails路由就会为控制器中的8个默认操作中的每一个创建8个url。 For an example let's say your controller is users_controller.rb then, you set it in routes.rb as resources :users this would allow the following methods, 举例来说,假设您的控制器为users_controller.rb,然后将其在route.rb中设置为resources :users这将允许以下方法,

users     GET    /users(.:format)                        users#index
          POST   /users(.:format)                        users#create
new_user  GET    /users/new(.:format)                    users#new
edit_user GET    /users/:id/edit(.:format)               users#edit
user      GET    /users/:id(.:format)                    users#show
          PATCH  /users/:id(.:format)                    users#update
          PUT    /users/:id(.:format)                    users#update
          DELETE /users/:id(.:format)                    users#destroy

So, when you build your view and set the form_for url as users_path and set the http method as POST the submission of the form would trigger the create action. 因此,当您构建视图并将form_for url设置为users_path并将http方法设置为POST时,表单的提交将触发create操作。 So, in the create action you should write all the code that is needed to trigger the model to save your record. 因此,在创建操作中,您应该编写触发模型以保存记录所需的所有代码。

Also, go through this document as well, 另外,还要仔细阅读本文档,

http://guides.rubyonrails.org/routing.html http://guides.rubyonrails.org/routing.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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