【问题标题】:Rails: how to redirect to "show" action of nested resource in a "create" action?Rails:如何在“创建”操作中重定向到嵌套资源的“显示”操作?
【发布时间】:2012-10-02 20:12:57
【问题描述】:

您好,我目前有 3 个模型:用户、相册、照片。我已经进行了注册,但还没有登录/会话,因为我试图先完成相册/照片的创建。但是,当我创建相册时,URL 会发生变化

http://localhost:3000/users/13/albums/new(没问题)

http://localhost:3000/albums/76/photos/76(问题)

这里的问题是: 1. user_id 从 url 中消失。 2. 它把我送到了错误的网址。正如您在下面看到的,我正在重定向到 [@user, @album]。这不应该是专辑控制器的表演动作吗?我想要像 /users/13/albums/1 这样的网址。相反,它把我送到photos#show。 3. 虽然链接错了,为什么相册id和照片id总是一样? 76/76 77/77 等等...我不知道这是从哪里来的..

这是我的文件:

相册控制器

def show
  @user = User.find(params[:user_id])
  @album = @user.albums.find(params[:id])
  @photo = @album.photos.build(params[:photo])
  respond_to do |format|
    if @album.save
      format.html { redirect_to album_photo_path(@album), notice: 'Album was successfully created.' }
      format.json { render json: @album, status: :created, location: @album}
    else
      format.html { render action: "new" }
      format.json { render json: @album.errors, status: :unprocessable_entity }
    end
  end
end

def update
end

def edit
end

def create
  @user = User.find(params[:user_id])
  @album = @user.albums.build(params[:album])
  respond_to do |format|
    if @user.save
      format.html { redirect_to [@user, @album], notice: 'Album was successfully created.' }
      format.json { render json: @album, status: :created, location: @album}
    else
      format.html { render action: "new" }
      format.json { render json: @album.errors, status: :unprocessable_entity }
    end
  end 
end

专辑/new.html.erb

<%= form_for (@album), url: user_albums_path, :html => { :id => "uploadform", :multipart => true } do |f| %>



<div>
    <%= f.label :name %>
    <%= f.text_field :name %>


    <%= f.label :description %>
    <%= f.text_area :description %>

    <br>

    <%=f.submit %>
</div>
<% end %>

配置/路由

Pholder::Application.routes.draw do
resources :users do
  resources :albums 
end

resources :albums do
  resources :photos
end

如果您需要更多文件,请告诉我。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    这是您的用例运行的一系列请求:

    首先,表单将一些数据提交给您的Album#create 操作。

    Album#create请求成功后,请求重定向到Albums#show动作。

    Albums#show 操作中,控制器使用您的当前用户和新相册实例化@user@album,然后在相册的photos 集合中构建一个新的照片对象。

    then 操作再次保存Album 记录。由于没有任何改变,这实际上并没有做任何事情。但它什么也没做成功,所以它继续将请求重定向到album_photo_path这就是梨形的地方。按照定义,这条路线在照片的父相册上下文中导致Photo#show 操作。该路由需要 两个 参数,一个相册和一个照片。正如在您的代码中调用的那样,它不应该工作——而是抛出一个路由错误异常。 (相信我,我试过了。)

    不过,我不会像那样纠结于细节,而是要盲推荐!

    听起来您不打算使用您的Album#show 操作来保存相册并通过格式错误的路由重定向到Photo#show。我认为这是您所有三个问题的根源。最后,我认为您的AlbumsControllershow 操作需要如下所示:

    def show
      @user = User.find(params[:user_id])
      @album = @user.albums.find(params[:id])
    end
    

    希望这会有所帮助!


    编辑以解决 Edmund 的评论:

    当然,您可以设置Album#show 操作以允许用户添加照片。这将涉及对我上面建议的两个更改。

    在您的控制器中,您将在@album 的照片集合上实例化一张新照片,就像您之前所做的一样:

    def show
      @user = User.find(params[:user_id])
      @album = @user.albums.find(params[:id])
      @photo = @album.photos.build
    end
    

    然后,在Album#show 模板(例如app/views/albums/show.html.erb)中,您将包含一个用于提交新照片的表单:

    <%= form_for [@user, @album, @photo] do |f| %>
      <%= f.text_field :caption %>
      <%= f.file_field :image %>
    <%- end %>
    

    此表单会将其内容提交给user_album_photos_path,您可能会注意到它尚不存在。所以最后的改变是将照片作为资源嵌套在routes.rb

    resources :users do
      resources :albums do
        resources :photos
      end
    end
    

    这将为您提供使用表单所需的路线。现在您只需要添加一个Photo#create 操作来处理表单提交,就可以开始比赛了!

    【讨论】:

    • 我实际上想在相册的显示操作中放置一个带有“photo#new”功能的表单(这样人们就可以看到相册中的图片并从一个页面上传新的)。这是不允许的吗?
    【解决方案2】:

    我相信您的创建操作应该如下所示:

    def create
      @user = User.find(params[:user_id])
      @album = @user.albums.build(params[:album])
      respond_to do |format|
        if @user.save
          format.html { redirect_to user_album_path(@album), notice: 'Album was successfully created.' }
          format.json { render json: @album, status: :created, location: @album}
        else
          format.html { render action: "new" }
          format.json { render json: @album.errors, status: :unprocessable_entity }
        end
      end 
    end
    

    【讨论】:

    • 当我将重定向更改为您提到的内容时,它给我一个表单提交错误路由错误No route matches {:action=&gt;"show", :controller=&gt;"albums", :user_id=&gt;#&lt;Album id: 83, name: "fsdafdssadf", created_at: "2012-10-03 02:32:18", updated_at: "2012-10-03 02:32:18", description: "fsdaads"&gt;}
    • @bigpotato 我需要将其更改为user_album_path(album: @album, user: current_user) 这也有效user_album_path(album_id: @album.id, user: current_user.id)
    猜你喜欢
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多