rails入门

原创 2016年05月30日 17:57:44

1、新建site

rails new SITENAME

手动终止,修改Gemfile,http://gems.ruby-china.org
bundle install 安装依赖

2、运行:

rails server
localhost:3000

3、生成控制器:

rails generate controller welcome index

4、修改路由:

root ‘welcome#index’ 根路径为welcome控制器的index方法
get ‘welcome/index’ 访问welcome/index时交给根方法,访问localhost:3000和访问localhost:3000/welcome/index效果相同

出现error:ExecJS::ProgramError in …
原因:js依赖没安装
解决:在Gemfile中添加 gem ‘coffee-script-source’, ‘1.8.0’
在命令行运行 bundle update coffee-script-source
http://stackoverflow.com/questions/28241981/rails-4-execjsprogramerror-in-pageswelcome

5、新建资源:

routes.rb中添加 resources :articles ,新建符合REST架构的资源
命令行运行rake/routes

$ bin/rake routes
      Prefix Verb   URI Pattern                  Controller#Action
    articles GET    /articles(.:format)          articles#index
             POST   /articles(.:format)          articles#create
 new_article GET    /articles/new(.:format)      articles#new
edit_article GET    /articles/:id/edit(.:format) articles#edit
     article GET    /articles/:id(.:format)      articles#show
             PATCH  /articles/:id(.:format)      articles#update
             PUT    /articles/:id(.:format)      articles#update
             DELETE /articles/:id(.:format)      articles#destroy
        root GET    /                            welcome#index

6、生成article控制器:

rails g controller articles     #generate可以简写成g

7、直接访问localhost:3000/articles/是访问index页面

控制器方法只能为public
在articles_controller.rb中定义空的new方法,在view/articles下新建new.html.rb文件,写入html内容,即可访问articles/new网页

8、new.html.rb中添加新建文章的表单:

问题是源代码显示form的action=”/articles/new”,提交表单显示没有post方法

<%= form_for :article do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

9、修改表单:

<%= form_for :article, url: articles_path do |f| %>

在rake routes中显示articles对应的URL是articles/,使得表单向这个路由发起POST请求,并自动调用create方法

10、新建create方法:

 def create
       render plain: params[:article].inspect
 end

11、生成article模型:

rails generate model Article title:string text:text

该操作生成models/articles.rb和db/migrate/….create_articles.rb

12、数据库迁移:

  rake db:migrate

13、修改create方法,与数据库连接

def create
  @article = Article.new(params[:article])

  @article.save
  redirect_to @article
end

params[:article]中各属性值会自动映射,很方便
但rails的安全机制不允许直接使用参数,要修改成

def create
  @article = Article.new(article_params)

  @article.save
  redirect_to @article
end

private
  def article_params
    params.require(:article).permit(:title, :text)
  end

明确说明允许使用哪些参数

14、此时提交表单显示没有show方法

controller

def show
  @article = Article.find(params[:id])
end

view

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

此时 localhost:3000/articles/id 网页将显示一篇文章

15、完成index方法,在访问localhost:3000/articles/时显示所有文章

def index
  @articles = Article.all
end
<h1>Listing articles</h1>

<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
  </tr>

  <% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
    </tr>
  <% end %>
</table>

16、添加链接

打开 app/views/welcome/index.html.erb 文件,改成这样:

<h1>Hello, Rails!</h1>
<%= link_to 'My Blog', controller: 'articles' %>

在localhost:3000/welcome/页面下出现My Blog链接,点击进入localhost:3000/articles/
接下来添加到其他页面的链接。先在 app/views/articles/index.html.erb 中添加“New Article”链接,放在 table 标签之前:

<%= link_to 'New article', new_article_path %>

然后在 app/views/articles/new.html.erb 中添加一个链接,位于表单下面,返回到 index 动作:

<%= form_for :article do |f| %>
  ...
<% end %>

<%= link_to 'Back', articles_path %>

最后,在 app/views/articles/show.html.erb 模板中添加一个链接,返回 index 动作,这样用户查看某篇文章后就可以返回文章列表页面了:

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<%= link_to 'Back', articles_path %>

17、添加表单验证:

 models/article.rb 中 显示article继承了ActiveRecord::Base类,可以使用Base类的方法进行数据验证
class Article < ActiveRecord::Base
  validates :title, presence: true,
                    length: { minimum: 5 }
end
 修改控制器
def new
  @article = Article.new
end

def create
  @article = Article.new(article_params)

  if @article.save
    redirect_to @article
  else
    render 'new'
  end
end

private
  def article_params
    params.require(:article).permit(:title, :text)
  end

在new方法中新建article对象,在create中通过判断article.save的返回值指定指向的网页,render方法将本次的article对象传给new使得渲染后的页面保留填写过的内容,而redirect_to方法会重新发起一次请求,转向articles页面

18、添加创建文章时的报错信息:

<%= form_for :article, url: articles_path do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', articles_path %>
 pluralize 是 Rails 提供的帮助方法,接受一个数字和字符串作为参数。如果数字比 1 大,字符串会被转换成复数形式
 之所以在new方法中创建article对象是为了传入视图模板中,否则这里的article就是nil

19、添加edit,页面指向update方法:

 new  --->  create
 edit  --->  update
def edit
  @article = Article.find(params[:id])
end
<h1>Editing article</h1>

<%= form_for :article, url: article_path(@article), method: :patch do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', articles_path %>

method: :patch 选项告诉 Rails,提交这个表单时使用 PATCH 方法发送请求。根据 REST 架构,更新资源时要使用 HTTP PATCH 方法。
form_for可以传入对象和symbol,index页面中@articles是对象,edit中 : article 是symbol

def update
  @article = Article.find(params[:id])

  if @article.update(article_params)
    redirect_to @article
  else
    render 'edit'
  end
end

private
  def article_params
    params.require(:article).permit(:title, :text)
  end

不用把所有的属性都提供给 update 动作。例如,如果使用 @article.update(title: ‘A new title’),Rails 只会更新 title 属性,不修改其他属性。

20、index页面加入edit链接:

<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="2"></th>
  </tr>

<% @articles.each do |article| %>
  <tr>
    <td><%= article.title %></td>
    <td><%= article.text %></td>
    <td><%= link_to 'Show', article_path(article) %></td>
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
  </tr>
<% end %>
</table>

show页面加入edit链接:

...

<%= link_to 'Back', articles_path %>
| <%= link_to 'Edit', edit_article_path(@article) %>

21、添加局部视图消除重复代码:

新建 app/views/articles/_form.html.erb 文件,写入以下代码:

<%= form_for @article do |f| %>
  <% if @article.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@article.errors.count, "error") %> prohibited
      this article from being saved:</h2>
    <ul>
    <% @article.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

之所以能在两个动作中共用一个 form_for,是因为 @article 是一个资源,对应于符合 REST 架构的路由,Rails 能自动分辨使用哪个地址和请求方法。

下面来修改 app/views/articles/new.html.erb 视图,使用新建的局部视图,把其中的代码全删掉,替换成:

<h1>New article</h1>

<%= render 'form' %>

<%= link_to 'Back', articles_path %>

然后按照同样地方法修改 app/views/articles/edit.html.erb 视图:

<h1>Edit article</h1>

<%= render 'form' %>

<%= link_to 'Back', articles_path %>

22、删除文章:

 注意rake/routes中删除的动作是DELETE,如果还使用 GET 请求,可以构建如下所示的恶意地址:
 <a href='http://example.com/articles/1/destroy'>look at this cat!</a>
def destroy
  @article = Article.find(params[:id])
  @article.destroy

  redirect_to articles_path
end
 index页面中加入删除链接:
<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="3"></th>
  </tr>

<% @articles.each do |article| %>
  <tr>
    <td><%= article.title %></td>
    <td><%= article.text %></td>
    <td><%= link_to 'Show', article_path(article) %></td>
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
    <td><%= link_to 'Destroy', article_path(article),
                    method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

:method 和 :’data-confirm’ 选项设置链接的 HTML5 属性,点击链接后,首先会显示一个对话框,然后发起 DELETE 请求。这两个操作通过 jquery_ujs 这个 JavaScript 脚本实现。生成程序骨架时,会自动把 jquery_ujs 加入程序的布局中(app/views/layouts/application.html.erb)。没有这个脚本,就不会显示确认对话框

23、创建评论模型:

 rails generate model Comment commenter:string body:text article:references

模板comment.rb中自动生成belongs_to :article
数据库迁移:
rake db:migrate
相对应的修改article.rb文件:

class Article < ActiveRecord::Base
  has_many :comments
  validates :title, presence: true,
                    length: { minimum: 5 }
end

24、修改路由文件:

resources :articles do
  resources :comments
end

这种做法叫嵌套资源,表明了文章和评论间的层级关系

25、生成控制器:

 rails generate controller Comments

修改articles/show视图,用户可以写评论

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Back', articles_path %>
| <%= link_to 'Edit', edit_article_path(@article) %>

26、定义create方法:

class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end

  private
    def comment_params
      params.require(:comment).permit(:commenter, :body)
    end
end

27、articles/show页面显示评论:

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Comments</h2>
<% @article.comments.each do |comment| %>
  <p>
    <strong>Commenter:</strong>
    <%= comment.commenter %>
  </p>

  <p>
    <strong>Comment:</strong>
    <%= comment.body %>
  </p>
<% end %>

<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Edit Article', edit_article_path(@article) %> |
<%= link_to 'Back to Articles', articles_path %>

28、新增局部视图 views/comments/_comment.html.erb:

<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>
  修改article的show页面:
<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Comments</h2>
<%= render @article.comments %>

<h2>Add a comment:</h2>
<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

<%= link_to 'Edit Article', edit_article_path(@article) %> |
<%= link_to 'Back to Articles', articles_path %>

29、新建 app/views/comments/_form.html.erb

<%= form_for([@article, @article.comments.build]) do |f| %>
  <p>
    <%= f.label :commenter %><br>
    <%= f.text_field :commenter %>
  </p>
  <p>
    <%= f.label :body %><br>
    <%= f.text_area :body %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

修改article/show

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>

<p>
  <strong>Text:</strong>
  <%= @article.text %>
</p>

<h2>Comments</h2>
<%= render @article.comments %>

<h2>Add a comment:</h2>
<%= render "comments/form" %>

<%= link_to 'Edit Article', edit_article_path(@article) %> |
<%= link_to 'Back to Articles', articles_path %>

%= render “comments/form” %,rails会自动识别form

30、删除评论:

先在 app/views/comments/_comment.html.erb 局部视图中加入删除评论的链接:

<p>
  <strong>Commenter:</strong>
  <%= comment.commenter %>
</p>

<p>
  <strong>Comment:</strong>
  <%= comment.body %>
</p>

<p>
  <%= link_to 'Destroy Comment', [comment.article, comment],
               method: :delete,
               data: { confirm: 'Are you sure?' } %>
</p>
class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to article_path(@article)
  end

  def destroy
    @article = Article.find(params[:article_id])
    @comment = @article.comments.find(params[:id])
    @comment.destroy
    redirect_to article_path(@article)
  end

  private
    def comment_params
      params.require(:comment).permit(:commenter, :body)
    end
end

31、删除文章时要删除与其对应的评论:

class Article < ActiveRecord::Base
  has_many :comments, dependent: :destroy
  validates :title, presence: true,
                    length: { minimum: 5 }
end

32、简单认证:

class ArticlesController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]

  def index
    @articles = Article.all
  end

  # snipped for brevity
class CommentsController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy

  def create
    @article = Article.find(params[:article_id])
    ...
  end

  # snipped for brevity
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Rails抛异常ExecJS::RuntimeError in Welcome#index

今天按照Rails入门安装RoR,

rails入门详细笔记

  • 2016年05月23日 16:31
  • 294KB
  • 下载

Rails3入门之十一 建立一个多模型的form

你的blog还有一个功能是给博客加上tag。需要实现这个功能的话需要你在一个form中实现多个模型的交互。 rails支持嵌套的form。 为了实现这些,我们将添加每个post多个tag。...
  • kucss
  • kucss
  • 2011年12月13日 23:05
  • 1177

Rails3入门之八 重构

现在我们的博客和评论都可以工作了,但是我们打开app/views/posts/show.html.erb 会发现,这个代码太长了显得不好看。我们可以用partials来简化它。 8.1 处...
  • kucss
  • kucss
  • 2011年11月15日 23:16
  • 680

Ruby on Rails 入门之:(18) ruby线程控制,线程同步

在Ruby中线程是用户级线程并依赖与操作系统。线程是进程中的一个实体,是被系统独立调度和分配的基本单位。线程可以与同属于同样个进程的其他线程共同共享进程的全部资源。但是线程不拥有资源,只需要一点在运行...

Ruby on Rails 入门之:(19) ruby线程同步控制

在Ruby中,提供三种实现同步的方式,分别是: 1. 通过Mutex类实现线程同步 2. 监管数据交接的Queue类实现线程同步 3. 使用ConditionVariable实现同步...

rails 入门文档

  • 2016年09月13日 02:16
  • 284KB
  • 下载

ruby on rails 入门教程

  • 2013年12月18日 11:44
  • 12.43MB
  • 下载

Ruby on Rails 入门之:(14) Ruby中的继承

Ruby中使用 #encoding:gbk class Father def show puts "hello father"; end end class Son < F...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:rails入门
举报原因:
原因补充:

(最多只允许输入30个字)