使用嵌套资源

时间:2015-07-07 15:48:16

标签: ruby-on-rails

我在路由rails应用程序以使用新的编辑表单时遇到问题。 路由使用URL中的用户名。

               lists GET    /lists(.:format)                         lists#index
                     POST   /user/:username/lists(.:format)          lists#create
            new_list GET    /user/:username/lists/new(.:format)      lists#new
           edit_list GET    /user/:username/lists/:id/edit(.:format) lists#edit
                list GET    /user/:username/lists/:id(.:format)      lists#show
                     PATCH  /user/:username/lists/:id(.:format)      lists#update
                     PUT    /user/:username/lists/:id(.:format)      lists#update
                     DELETE /user/:username/lists/:id(.:format)      lists#destroy
                root GET    /                                        static#welcome
           show_user GET    /user/:id(.:format)                      users#show

我的routes.rb -

  get 'lists', to: 'lists#index', as: :lists, via: 'get'

  scope 'user/:username' do
      resources :lists, except: [:index]
  end

我的共享表单,用于更新和创建 -

<%= form_for [@user, @list], url: list_path(@user, @list) do |f| %>

使用上述设置,我可以正确编辑列表,但如果我导航到列表#new,我会收到以下错误 -

No route matches {:action=>"show", :controller=>"lists", :id=>nil, :username=>"test"} missing required keys: [:id]

如果我将表单中的路径复数为url: lists_path(@user, @list),则new页面现在会加载,但在尝试创建时,我会收到以下错误 -

No route matches [POST] "/lists.test"

如何修复这些路线,以便我可以使用相同的共享表单进行编辑和创建?

添加控制器代码 -

class ListsController < ApplicationController
  before_action :set_list, only: [:show, :edit, :update, :destroy]

  def index
      @lists = List.all
  end

  def show
  end

  # GET /lists/new
  def new
    @list = List.new
    @user = User.find_by(username: params[:username])
  end

  def edit
    @user = User.find_by(username: params[:username])
  end


  def create
    @list = current_user.lists.new(list_params)

    respond_to do |format|
      if @list.save
        format.html { redirect_to list_path(@list.user.username, @list.id), notice: 'List was successfully created.' }
      else
        format.html { render :new }
      end
    end
  end


  def update
    respond_to do |format|
      if @list.update(list_params)
        format.html { redirect_to list_path(@list.user.username, @list.id), notice: 'List was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
  end

  def destroy
    @list.destroy
    respond_to do |format|
      format.html { redirect_to lists_url, notice: 'List was successfully destroyed.' }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_list
      @list = List.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def list_params
      params.require(:list).permit(:name, :category, :user_id)
    end
end

1 个答案:

答案 0 :(得分:0)

试试这个 - 将form_for中的:url值更改为[[@list], :username => @user.username]

像这样:

<%= form_for [@user, @list], url: [[@list], :username => @user.username] do |f| %>