0

我是 Rails 的新手,正在申请大学成员(教师和学生)可以在其中创建帖子并对其发表评论。稍后我希望在其中添加嵌套(祖先)和积分系统。

我有帖子、评论和会员模型。Post 模型是通过 Scaffolding 制作的,Member 模型是在 Devise 的帮助下制作的,Comment 只是一个模型。

在我的帖子显示页面中,我想在帖子下方发表评论,我已经取得了一些进展(多亏了我才知道很多)但现在我遇到了一个问题,每当我尝试发布一条空白评论,rails 正在重定向到编辑页面。如何更改此设置以使 rails 仅停留在显示页面上并显示错误?

为此,我进行了一些搜索,在 post_controller.rb 中创建了一个新方法“update_comments”,并尝试修改 forms_for 标记属性,如下面的代码所示,但现在提交时出现路由错误。

应用程序/模型/member.rb

class Member < ActiveRecord::Base
  #Associations
  belongs_to :department

  has_one :student, :dependent => :destroy
  accepts_nested_attributes_for :student

  has_one :nstudent, :dependent => :destroy
  accepts_nested_attributes_for :nstudent

  has_many :posts, :dependent => :destroy
  has_many :comments, :dependent => :destroy  
end

应用程序/模型/post.rb

class Post < ActiveRecord::Base

  #Associations
  belongs_to :member
  has_many :comments, :dependent => :destroy

  accepts_nested_attributes_for :comments
end

应用程序/模型/comment.rb

class Comment < ActiveRecord::Base

  # Associations
  belongs_to :member
  belongs_to :post

  validates_presence_of :content
end

配置/路由.rb

Urdxxx::Application.routes.draw do
  devise_for :members

  resources :posts do
    member do
     get 'update_comment'
    end
  end

  root :to => 'posts#index'

应用程序/控制器/posts_controller.rb

class PostsController < ApplicationController
  # Devise filter that checks for an authenticated member
  before_filter :authenticate_member!

# GET /posts
# GET /posts.json
def index
  @posts = Post.find(:all, :order => 'points DESC')

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @posts }
  end
end
...
# GET /posts/1/edit
def edit
  @post = Post.find(params[:id])    
end

# POST /posts
# POST /posts.json
def create
  @post = Post.new(params[:post])
  @post.member_id = current_member.id if @post.member_id.nil?

  respond_to do |format|
    if @post.save
      format.html { redirect_to @post, notice: 'Post was successfully created.' }
      format.json { render json: @post, status: :created, location: @post }
    else
      format.html { render action: "new" }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end

# PUT /posts/1
# PUT /posts/1.json
def update
  @post = Post.find(params[:id])

  respond_to do |format|
    if @post.update_attributes(params[:post])
      format.html { redirect_to @post, notice: 'Post was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: "edit" }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end

# DELETE /posts/1
# DELETE /posts/1.json
def destroy
  @post = Post.find(params[:id])
  @post.destroy

  respond_to do |format|
    format.html { redirect_to posts_url }
    format.json { head :no_content }
  end
end

# Not made by scaffold
def update_comment
  @post = Post.find(params[:id])        

  respond_to do |format|
    if @post.update_attributes(params[:post])
      format.html { redirect_to @post, notice: 'Comment was successfully created.' }
      format.json { head :no_content }
    else
      format.html { render action: "show" }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end
end

app/views/posts/show.html.erb

<p> Have your say </p>
<%= form_for @post, :url => {:action => 'update_comment'} do |p| %>
  <%= p.fields_for :comments do |c| %>
     <!-- Following 3 lines saved my life -->
      <% if c.object.new_record? %>
        <%= c.text_area :content, :rows => 4 %>
        <%= c.hidden_field :member_id, value: current_member.id %>
      <% end %>
   <% end %>
   <%= p.submit "Reply" %>
<% end %>

我的展示页面图片:http: //i.stack.imgur.com/TBgKy.png

发表评论:http: //i.stack.imgur.com/JlWeR.png

更新:

回过头来,按照肯所说的在这里进行了更改。我不知道如何,但它现在有效。

应用程序/控制器/posts_controller.rb

def update
  @post = Post.find(params[:id])

  respond_to do |format|
  if @post.update_attributes(params[:post])
    format.html { redirect_to @post, notice: 'Post was successfully updated.' }
    format.json { head :no_content }
  elsif :comments
    format.html { render action: "show" }
    format.json { render json: @post.errors, status: :unprocessable_entity }
  else
    format.html { render action: "edit" }
    format.json { render json: @post.errors, status: :unprocessable_entity }
  end
  end
end
4

2 回答 2

0

您需要更新路由中的方法类型,还需要将表单发布方法设置为您的新操作,当您提交表单时,它是发布请求而不是获取请求。

Urdxxx::Application.routes.draw do
  devise_for :members

  resources :posts do
    collection do
     post :update_comment
    end
  end

  root :to => 'posts#index'

<p> Have your say </p>
<%= form_for :post, :url => {:action => 'update_comment'} do |p| %>
  <%= p.fields_for :comments do |c| %>
     <!-- Following 3 lines saved my life -->
      <% if c.object.new_record? %>
        <%= c.text_area :content, :rows => 4 %>
        <%= c.hidden_field :member_id, value: current_member.id %>
      <% end %>
   <% end %>
   <%= p.submit "Reply" %>
<% end %>
于 2012-03-26T06:19:19.280 回答
0

您不需要自定义方法。它不是很 RESTful。有关 REST 的信息,请参见例如http://www.sitepoint.com/restful-rails-part-i/。这不是有理由使用自定义方法的情况。

每当您发现自己添加自定义方法时,您都应该仔细考虑是否有必要。通常,如果您需要自定义方法,您实际需要的是另一个控制器(或一组不同的控制器)。

这里的更新方法就是你所需要的。如果您真的想在更新失败后转到 show 方法(尽管我不知道为什么),那么render edit在更新失败后更改 update 方法中的块中的调用。

看起来你真正的问题是编辑视图没有显示错误。虽然脚手架生成的视图应该这样做,但也许你改变了它。

如果您错过了它,您也可以从这个截屏视频中受益:

http://railscasts.com/episodes/196-nested-model-form-part-1

于 2012-03-26T06:27:08.683 回答