rails入门

来源:互联网 发布:锦衣卫同知是什么官职 编辑:程序博客网 时间:2024/05/29 19:26

1、新建site

rails new SITENAME

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

2、运行:

rails serverlocalhost: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#newedit_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 @articleend

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

def create  @article = Article.new(article_params)  @article.save  redirect_to @articleendprivate  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.allend
<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.newenddef create  @article = Article.new(article_params)  if @article.save    redirect_to @article  else    render 'new'  endendprivate  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'  endendprivate  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_pathend
 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 :commentsend

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

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)    endend

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)    endend

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
0 0
原创粉丝点击