簡體   English   中英

Rails 4嵌套淺路由:如何在子控制器中獲取父ID?

[英]Rails 4 nested shallow routes: how to get parent id in child controller?

在我的Rails 4應用程序中,有四種模型:

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
  has_many: :posts
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Post < ActiveRecord::Base
  belongs_to :calendar
end

有了這個路由:

Rails.application.routes.draw do

  root to: 'pages#home'

  devise_for :users, :path => 'account'

  resources :calendars do
    resources :posts, shallow: true
  end

end

這給出了這些路線:

Prefix Verb   URI Pattern                                 Controller#Action
                   posts GET    /posts(.:format)                            posts#index
                         POST   /posts(.:format)                            posts#create
                new_post GET    /posts/new(.:format)                        posts#new
               edit_post GET    /posts/:id/edit(.:format)                   posts#edit
                    post GET    /posts/:id(.:format)                        posts#show
                         PATCH  /posts/:id(.:format)                        posts#update
                         PUT    /posts/:id(.:format)                        posts#update
                         DELETE /posts/:id(.:format)                        posts#destroy
                    root GET    /                                           pages#home
        new_user_session GET    /account/sign_in(.:format)                  devise/sessions#new
            user_session POST   /account/sign_in(.:format)                  devise/sessions#create
    destroy_user_session DELETE /account/sign_out(.:format)                 devise/sessions#destroy
           user_password POST   /account/password(.:format)                 devise/passwords#create
       new_user_password GET    /account/password/new(.:format)             devise/passwords#new
      edit_user_password GET    /account/password/edit(.:format)            devise/passwords#edit
                         PATCH  /account/password(.:format)                 devise/passwords#update
                         PUT    /account/password(.:format)                 devise/passwords#update
cancel_user_registration GET    /account/cancel(.:format)                   devise/registrations#cancel
       user_registration POST   /account(.:format)                          devise/registrations#create
   new_user_registration GET    /account/sign_up(.:format)                  devise/registrations#new
  edit_user_registration GET    /account/edit(.:format)                     devise/registrations#edit
                         PATCH  /account(.:format)                          devise/registrations#update
                         PUT    /account(.:format)                          devise/registrations#update
                         DELETE /account(.:format)                          devise/registrations#destroy
       user_confirmation POST   /account/confirmation(.:format)             devise/confirmations#create
   new_user_confirmation GET    /account/confirmation/new(.:format)         devise/confirmations#new
                         GET    /account/confirmation(.:format)             devise/confirmations#show
             user_unlock POST   /account/unlock(.:format)                   devise/unlocks#create
         new_user_unlock GET    /account/unlock/new(.:format)               devise/unlocks#new
                         GET    /account/unlock(.:format)                   devise/unlocks#show
          calendar_posts GET    /calendars/:calendar_id/posts(.:format)     posts#index
                         POST   /calendars/:calendar_id/posts(.:format)     posts#create
       new_calendar_post GET    /calendars/:calendar_id/posts/new(.:format) posts#new
                         GET    /posts/:id/edit(.:format)                   posts#edit
                         GET    /posts/:id(.:format)                        posts#show
                         PATCH  /posts/:id(.:format)                        posts#update
                         PUT    /posts/:id(.:format)                        posts#update
                         DELETE /posts/:id(.:format)                        posts#destroy
               calendars GET    /calendars(.:format)                        calendars#index
                         POST   /calendars(.:format)                        calendars#create
            new_calendar GET    /calendars/new(.:format)                    calendars#new
           edit_calendar GET    /calendars/:id/edit(.:format)               calendars#edit
                calendar GET    /calendars/:id(.:format)                    calendars#show
                         PATCH  /calendars/:id(.:format)                    calendars#update
                         PUT    /calendars/:id(.:format)                    calendars#update
                         DELETE /calendars/:id(.:format)                    calendars#destroy

最后,這是posts_controller.rb的內容:

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]

  # GET /posts
  # GET /posts.json
  def index
    @posts = Post.all
  end

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

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # POST /posts
  # POST /posts.json
  def create
    @calendar = Calendar.find(params[:calendar_id])
    @post = @calendar.posts.create(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

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

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @calendar = Calendar.find(params[:calendar_id])
    @post.destroy
    respond_to do |format|
      format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:date, :time, :subject, :format, :copy, :media)
    end
end

我一直遇到類似的錯誤。

問題#1 :當我嘗試從show.html.erb日歷視圖中刪除帖子時:

<h2><%= @calendar.name %> Calendar</h2>

<h3>Posts</h3>
<% if @calendar.posts.any? %>
    <table>
        <tr>
            <th>Date</th>
            <th>Time</th>
            <th>Subject</th>
            <th>Format</th>
            <th>Copy</th>
            <th>Media</th>
        </tr>
  <% @calendar.posts.each do |post| %>
        <tr>
        <td><%= post.date %></td>
            <td><%= post.time %></td>
            <td><%= post.subject %></td>
            <td><%= post.format %></td>
            <td><%= post.copy %></td>
            <td><%= post.media %></td>
        <td><%= link_to 'View', post %></td>
        <td><%= link_to 'Update', edit_post_path(post) %></td>
        <td><%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
    </table>
  <% end %>
...

我明白了:

ActiveRecord::RecordNotFound in PostsController#destroy
Couldn't find Calendar with 'id'=

問題2 :當我嘗試從edit.html.erb帖子視圖更新帖子時:

<h1>Editing Post</h1>

<%= render 'form' %>

<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>

我明白了:

ActiveRecord::RecordNotFound in PostsController#update
Couldn't find Calendar with 'id'=

問題3 :當我嘗試從show.html.erb帖子視圖返回show.html.erb日歷視圖時:

<div>
    <p>Date</p>
    <%= @post.date %>
</div>
<div>
    <p>Time</p>
    <%= @post.time %>
</div>
<div>
    <p>Subject</p>
    <%= @post.subject %>
    </div>
<div>
    <p>Format</p>
    <%= @post.format %>
    </div>
<div>
    <p>Copy</p>
    <%= @post.copy %>
</div>
<div>
    <p>Media</p>
    <%= @post.media %>
</div>

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

我明白了:

ActiveRecord::RecordNotFound in PostsController#show
Couldn't find Calendar with 'id'=

如果我對錯誤的解釋是正確的,那么每次問題似乎都是我無法檢索post所屬的calendarid

換句話說,我無法從子(post)控制器中檢索父(日歷)id。

我相信這是一個與我的嵌套淺層資源以及我在視圖中構建鏈接的方式相關的問題。

我無法弄清楚如何使這些鏈接工作。

如果您可以為我提供解決方案 - 最重要的是推理 - 對於上述三種情況之一,我絕對能夠為其他兩種情況提出解決方案。

任何的想法?

我找到了解決我的三個問題的每個問題。

問題#1 :我換了:

format.html { redirect_to calendar_path(@calendar), notice: 'Post was successfully destroyed.' }

有:

format.html { redirect_to calendar_path(@post.calendar_id), notice: 'Post was successfully destroyed.' } 

posts_controller.rb

問題#2 :我換了:

<%= link_to 'Back', posts_path %> 

有:

<%= link_to 'Back', calendar_path(@post.calendar_id) %>

edit.html.erb帖子視圖中。

問題3 :我換了:

<%= link_to 'Back', posts_path %>

有:

calendar_path(@post.calendar_id)

show.html.erb帖子視圖中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM