【问题标题】:Nested resources in railsRails 中的嵌套资源
【发布时间】:2015-01-05 13:51:04
【问题描述】:

我正在尝试制作一个简单的 Rails 应用程序,用户可以在其中创建任意数量的播放列表。我对 Rails 很陌生,想知道是否应该像这样嵌套资源:

Rails.application.routes.draw do
  resources :users do
    resources :playlists
  end

当我rake routes 时,这样做会产生这种情况:

            Prefix Verb   URI Pattern                                  Controller#Action
    user_playlists GET    /users/:user_id/playlists(.:format)          playlists#index
                   POST   /users/:user_id/playlists(.:format)          playlists#create
 new_user_playlist GET    /users/:user_id/playlists/new(.:format)      playlists#new
edit_user_playlist GET    /users/:user_id/playlists/:id/edit(.:format) playlists#edit
     user_playlist GET    /users/:user_id/playlists/:id(.:format)      playlists#show
                   PATCH  /users/:user_id/playlists/:id(.:format)      playlists#update
                   PUT    /users/:user_id/playlists/:id(.:format)      playlists#update
                   DELETE /users/:user_id/playlists/:id(.:format)      playlists#destroy
             users GET    /users(.:format)                             users#index
                   POST   /users(.:format)                             users#create
          new_user GET    /users/new(.:format)                         users#new
         edit_user GET    /users/:id/edit(.:format)                    users#edit
              user GET    /users/:id(.:format)                         users#show
                   PATCH  /users/:id(.:format)                         users#update
                   PUT    /users/:id(.:format)                         users#update
                   DELETE /users/:id(.:format)                         users#destroy
              root GET    /                                            default_pages#home
            signup GET    /signup(.:format)                            users#new
            signin GET    /signin(.:format)                            users#signin

我可以成功访问我有此链接的 /users/1/playlists(在播放列表的 index.html.erb 中):

<%= link_to 'New Playlist', new_user_playlist_path(params[:user_id])%>

但是点击它会给我这个错误:

     undefined method `playlists' for nil:NilClass

   Extracted source (around line #18):
   16       # GET /playlists/new
   17       def new
   18         @playlist = @user.playlists.new
   19       end
   20       # GET /playlists/1/edit

这就是我的 playlist_controller 的样子:

class PlaylistsController < ApplicationController
  before_action :set_playlist, only: [:show, :edit, :update, :destroy]
                :set_user

  # GET /playlists
  # GET /playlists.json
  def index
    @playlists = Playlist.all
  end

  # GET /playlists/1
  # GET /playlists/1.json
  def show
  end

  # GET /playlists/new
  def new
    @playlist = @user.playlists.new
  end

  # GET /playlists/1/edit
  def edit
  end

  # POST /playlists
  # POST /playlists.json
  def create
    @playlist = @user.playlists.new(playlist_params)

    respond_to do |format|
      if @playlist.save
        format.html { redirect_to @user.playlist, notice: 'Playlist was successfully created.' }
        format.json { render :show, status: :created, location: @playlist }
      else
        format.html { render :new }
        #format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /playlists/1
  # PATCH/PUT /playlists/1.json
  def update
    respond_to do |format|
      if @playlist.update(playlist_params)
        format.html { redirect_to @playlist, notice: 'Playlist was successfully updated.' }
        format.json { render :show, status: :ok, location: @playlist }
      else
        format.html { render :edit }
        format.json { render json: @playlist.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /playlists/1
  # DELETE /playlists/1.json
  def destroy
    @playlist.destroy
    respond_to do |format|
      format.html { redirect_to playlists_url, notice: 'Playlist was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_user
      @user = User.find_by(params[:user_id])
    end
    # Use callbacks to share common setup or constraints between actions.
    def set_playlist
      @playlist = Playlist.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def playlist_params
      params.require(:playlist).permit(:user_id, :title, :img)
    end
end

我的想法是,由于预期的 URL 应该看起来像 users/1/playlists/1,我需要传递两个变量,一个用于 user_id,一个用于播放列表 id(某种),但我不知道具体在哪里/如何...有人可以帮帮我吗?

谢谢

【问题讨论】:

  • 您是否在User 模型上设置了关系? has_many :playlists
  • 另外,您可能想使用@user.playlists.build。注意.build,它将自动设置关联的外键。
  • 我已经相应地设置了模型,谢谢。我会在哪里使用 .build?
  • 当您在 new 操作下设置 @playlist 时。 @playlist = @user.playlists.build。另外,我认为您不希望在index 下使用Playlist.all。由于播放列表与User 相关联,因此可能应该是@playlists = @user.playlists
  • 这很有意义,谢谢!由于我只是在复制教程并在学习时修复错误,因此我还没有发现。

标签: ruby-on-rails controller routes nested-routes


【解决方案1】:

我认为问题出在before_action,这就是未设置@user 的原因。尝试在行下再添加一次before_action before_action :set_playlist, only: [:show, :edit, :update, :destroy]

class PlaylistsController < ApplicationController
  before_action :set_playlist, only: [:show, :edit, :update, :destroy]
  before_action :set_user, only: [:new, :create]

  ...
end

UPD

我又找到了一个地方。 尝试在您的视图中使用@usernew_user_playlist_path(@user),应该已经从before_action实例化了

【讨论】:

  • 起初我收到这个错误:ActiveRecord::InverseOfAssociationNotFoundError in PlaylistsController#new 找不到用户的反向关联(用户中的播放列表)我记得我的播放列表模型中有这个:类Playlist
  • 你可以在这里找到一些信息:guides.rubyonrails.org/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多