6

嗨,我目前有 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

让我知道您是否需要更多文件。

4

2 回答 2

6

Here's the series of requests that your use case runs through:

First, the form submits some data to your Album#create action.

After the Album#create request succeeds, the request is redirected to the Albums#show action.

In the Albums#show action, the controller instantiates @user and @album with your current User and the new Album, then builds a new Photo object within the Album's photos collection.

The action then saves the Album record again. Since nothing has changed, this doesn't actually do anything. But it does do nothing successfully, so it proceeds to redirect the request to album_photo_path, and this is where things go pear-shaped. This route, as defined, leads to a Photo#show action, in the context of the photo's parent Album. The route expects two arguments, an Album and a Photo. As invoked in your code, it shouldn't work—throwing a Routing Error exception instead. (Believe me, I tried.)

Instead of getting hung up on minutae like that, though, I'm going to make a blind recommendation instead!

It sounds like you didn't intend for your Album#show action to save the album and redirect to Photo#show via a malformed route. I think this is the source of all three of your issues. And, ultimately, I think your AlbumsController's show action needs to look like this:

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

Hope this helps!


Edited to address Edmund's comment:

Absolutely, you can set up the Album#show action to allow users to add photos. This would involve two changes to what I suggest above.

In your controller, you would instantiate a new Photo on @album's Photos collection, much as you had earlier:

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

Then, in the Album#show template (e.g. app/views/albums/show.html.erb), you'd include a form for submitting a new photo:

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

This form would submit its contents to the user_album_photos_path, which you may note does not yet exist. So the final change would be to nest Photos as a resource in routes.rb:

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

This will provide you with the route needed to use the form. Now you'll just need to add a Photo#create action to handle the form submission, and you're off to the races!

于 2012-10-02T21:05:59.720 回答
0

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

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
于 2012-10-02T20:20:38.510 回答