【问题标题】:Having an issue with Rails [GET] routesRails [GET] 路线有问题
【发布时间】:2013-10-04 19:30:38
【问题描述】:

我正在研究 Rails 框架和路由。我正在构建一个网站,用户可以在其中发布 Rails 文章和提示,并且我已经向我的网站添加了大量功能,但是我遇到了嵌套资源的问题。我希望我的用户创建帖子。我还希望同一用户和其他用户在帖子上留下 cmets。现在,棘手的部分是我需要一种方法让他们编辑自己的评论。因此,一旦他们转到帖子>评论>编辑,我就会收到No route matches [GET] "/posts/48/comments/edit",这是来自帖子展示模板。对于特定的帖子,我可以通过错误来判断它找不到该评论的 id 来编辑它。我确信这是嵌套资源问题,但我无法解决这个问题。看着我的代码,一切对我来说似乎都是机智的。有任何想法吗?提前感谢您提供任何见解。

routes.rb 文件

PostitTemplate::Application.routes.draw do
  root to: 'posts#index'

  get '/register', to: 'users#new'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  get '/logout', to: 'sessions#destroy'

  resources :users, only: [:create, :edit, :update]

  resources :posts, except: [:destroy] do
    member do
      post 'vote'
    end

    resources :comments, only: [:create, :edit, :update] do
      member do
        post 'vote'
      end
    end
  end

  resources :categories, only: [:new, :create]
end

cmets_controller

class CommentsController < ApplicationController
  before_action :require_user

  def create
    @post = Post.find(params[:post_id])
    @comment = Comment.new(params.require(:comment).permit(:body))
    @comment.post = @post
    @comment.creator = current_user

    if @comment.save
      flash[:notice] = "Your comment was created!"
      redirect_to post_path(@post)
    else
      render 'posts/show'
    end
  end

  def edit
    @comment = Comment.find(params[:id])
    @post = Post.find(params[:post_id])
  end

  def update
    @comment = Comment.find(params[:id])
    if @comment.update(comment_params)
      flash[:notice] = "You updated your comment!"
      redirect_to post_path
    else
      render :edit
    end
  end

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

  def set_comment
    @comment = Comment.find(params[:id])
  end
end

posts_controller

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :vote]
  before_action :require_user, only: [:new, :create, :edit, :update, :vote]
  before_action :require_creator, only:[:edit, :update]

  def index
    @posts = Post.all.page(params[:page]).per_page(10)
  end

  def show
    @comment = Comment.new
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    @post.creator = current_user

    if @post.save
      flash[:notice] = "You created a post!"
      redirect_to posts_path
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @post.update(post_params)
      flash[:notice] = "You updated the post!"
      redirect_to post_path(@post)
    else
      render :edit
    end
  end

  def vote
    Vote.create(voteable: @post, creator: current_user, vote: params[:vote])

    respond_to do |format|
      format.js { render :vote } # Renders views/posts/vote.js.erb
    end
  end

  private
  def post_params
    params.require(:post).permit(:url, :title, :description)
  end

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

  def require_creator
    access_denied if @post.creator != current_user
  end
end

show.html.erb(这是显示帖子模板,在第 33 行,我想链接到 cmets 控制器编辑操作)

<div class="page-header">
  <h2>
    <%= @post.title %>
    <small>
      posted by <%= link_to @post.creator.username %> about <%= time_ago_in_words(@post.created_at) + ' ago' %>
      | <%= link_to 'check out the link', fix_url(@post.url) %> |
      <%= link_to 'edit', edit_post_path(@post) %>
    </small>
  </h2>
</div>

<h3><%= @post.description %></h3>
  <%= render 'shared_partials/errors', errors_obj: @comment %>

  <%= form_for [@post, @comment] do |f| %>
    <%= f.text_area :body, :class=> "input", :placeholder=> "Comment goes here", :rows => "6" %>
    </br>
    <div class="button">
    <%= f.submit "Create a comment", class: 'btn btn-primary' %>
    </div>
  <% end %>

<div class="page-header">
  <h4>All Comments</h4>
</div>
<% @post.comments.each do |comment| %>
  <div class="comments">
    <h5><%= comment.body %></h5>
      <li>
       <small class="muted">
        posted by <%= link_to comment.creator.username %> about <%= time_ago_in_words(comment.created_at) + ' ago' %>
        <% if logged_in? && (comment.creator == current_user) %> |
        <%= link_to 'edit', edit_post_comment_path(@post, @comment) %> |
          <i class="icon-user icon"></i>
        <% end %>
      </small>
      </li>
  </div>
<% end %>

最后是我的 rake 路线

root_path    GET     /   posts#index
register_path    GET     /register(.:format)     users#new
login_path   GET     /login(.:format)    sessions#new
POST     /login(.:format)    sessions#create
logout_path  GET     /logout(.:format)   sessions#destroy
users_path   POST    /users(.:format)    users#create
edit_user_path   GET     /users/:id/edit(.:format)   users#edit
user_path    PATCH   /users/:id(.:format)    users#update
PUT  /users/:id(.:format)    users#update
vote_post_path   POST    /posts/:id/vote(.:format)   posts#vote
vote_post_comment_path   POST    /posts/:post_id/comments/:id/vote(.:format)     comments#vote
post_comments_path   POST    /posts/:post_id/comments(.:format)  comments#create
edit_post_comment_path   GET     /posts/:post_id/comments/:id/edit(.:format)     comments#edit
post_comment_path    PATCH   /posts/:post_id/comments/:id(.:format)  comments#update
PUT  /posts/:post_id/comments/:id(.:format)  comments#update
posts_path   GET     /posts(.:format)    posts#index
POST     /posts(.:format)    posts#create
new_post_path    GET     /posts/new(.:format)    posts#new
edit_post_path   GET     /posts/:id/edit(.:format)   posts#edit
post_path    GET     /posts/:id(.:format)    posts#show
PATCH    /posts/:id(.:format)    posts#update
PUT  /posts/:id(.:format)    posts#update
categories_path  POST    /categories(.:format)   categories#create
new_category_path    GET     /categories/new(.:format)   categories#new

【问题讨论】:

    标签: ruby-on-rails ruby rails-routing


    【解决方案1】:

    替换

    <%= link_to 'edit', edit_post_comment_path(@post, @comment) %>
    

    <%= link_to 'edit', edit_post_comment_path(@post, comment) %>
    

    您需要传递当前评论,而不是新评论。

    此外,您不一定必须嵌套 comment 资源。

    【讨论】:

    • 谢谢你。现在,当我更新我的评论时,我收到一个 ActiveRecord 错误 ActiveRecord::RecordNotFound in PostsController#showCouldn't find Post with id=69。这个错误出现在我的post_controller def set_post 的第 56 行附近
    • Betjamin,我有点困惑。你是说我的 cmets 控制器或后控制器需要@post = Post.find(params[:id])?在更新动作中。我可以更新我的帖子并很好地编辑它们,但我只是想更新我对该帖子的评论
    • 忽略我的评论。我误读了您的原始回复。要解决此问题,您需要在 def set_post 操作中将 def @post = Post.find(params[:id]) 更改为 def @post = Post.find(params[:post_id])
    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 2015-10-11
    • 2013-06-08
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    相关资源
    最近更新 更多