新手问题 控制器中的实例对象?

wwwicbd · 2016年02月29日 · 最后由 jpman 回复于 2016年03月01日 · 1426 次阅读
class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  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

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

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

疑问出处:新手引导的5.10小节 http://guides.ruby-china.org/getting_started.html

step1. 新建文章 /articles/new,填表单,submit 后 post给create方法 step2. 如果有符合save条件就重定向到 /articles/:id , 疑问:既然重定向了,也就是实例对象传不到show操作了吧,那为什么这样写呢? redirect_to @article step3. 如果不符合条件就重新渲染new方法,这时候显示errors;疑问:此时的URL变为 http://localhost:3000/articles ,WHY?

共收到 10 条回复

去看redirect_to源码你就明白了,@article是怎么转化为url的

你第三个问题有问题吧,感觉不会出现你说的这样喃。

#2楼 @qinfanpeng 确实如此哟~ 所以我也奇怪为什么会是 /articles

  1. redirect_to @article 是为了方便少写代码,等价于 redirect_to article_url(@article)。
  2. 关于setup 3的疑问, step 1 说了,点击 submit 会 post 给 create 方法,create 方法的 url 就是http://localhost:3000/articles,只不过是 post 请求。

#4楼 @nowherekai 可是render new为什么不是这个呢new_article GET /articles/new(.:format) articles#new,我想 渲染方法和提交方法应该是分开的吧?

#5楼 @wwwicbd render new 只是负责把你的 new.html.erb 模版渲染成html而已。 你这里说的渲染方法和提交方法没有任何关联, 如果你想让 url 变成 http://localhost:3000/articles/new. 你需要用 redirect_to

如六楼所说。guide看完了吗,没有的话先看guide,能解决你很多疑问,比如这里有对render和redirect_to的解释。

#6楼 @jpman Thanks! post之后,不符合过滤条件就重新渲染new方法对应的new.html.erb,和new方法无关,此时还处在create方法下,所以路径是/articles,对吧

#8楼 @wwwicbd 不对 render 是转发 也就是服务器内部处理 与前台无关,所以URL不变, render 'new' 是指向new action 如果 使用render : template=> XXXX 才是直接渲染页面

#9楼 这里我查了一下api 发现 render 'new' 会自动转换成 render action: 'new'. 但是我在这个controller 里没有定义 new action 的时候 依然可以正常渲染, 于是我又google 了一下 发现了这篇文章 http://climber2002.github.io/blog/2015/02/21/how-rails-finds-your-templates-part-1/ 这里 render 方法 找到 template文件 的全过程.

 if (options.keys & [:partial, :file, :template]).empty?
   options[:prefixes] ||= _prefixes
 end

options[:template] ||= (options[:action] || action_name).to_s

当没有 option[:template] 的时候 , 会得到一个 options[:prefixes], 然后 option[:action] 会赋值给 option[:template]

所以这里 render action: 'new' 和 controller 里的 new action 是没有任何关系的。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册