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

wwwicbd · 2016年02月29日 · 最后由 jpman 回复于 2016年03月01日 · 1991 次阅读
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?

去看 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 是没有任何关系的。

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