【问题标题】:Rails 4 Nested Routing Back to Parent's Show PageRails 4嵌套路由返回父显示页面
【发布时间】:2016-11-13 19:20:03
【问题描述】:

在我的网络应用程序中,我创建了两个模块;客户和工人。我的问题是我无法创建从workers#index 到clients#show 的“返回”链接。换句话说,我想在 URL 中创建这个:

http://localhost:3000/clients/1

我认为这与未输入正确的 URL 助手有关。当我运行 rake 路由时,我看到了我想要的路径,这让我相信我已经正确地嵌套了资源。但是,我似乎无法输入正确的参数以返回 client#show 页面而不是 clients#index。

Prefix Verb   URI Pattern                                    Controller#Action
    client_workers GET    /clients/:client_id/workers(.:format)          workers#index
                   POST   /clients/:client_id/workers(.:format)          workers#create
 new_client_worker GET    /clients/:client_id/workers/new(.:format)      workers#new
edit_client_worker GET    /clients/:client_id/workers/:id/edit(.:format) workers#edit
     client_worker GET    /clients/:client_id/workers/:id(.:format)      workers#show
                   PATCH  /clients/:client_id/workers/:id(.:format)      workers#update
                   PUT    /clients/:client_id/workers/:id(.:format)      workers#update
                   DELETE /clients/:client_id/workers/:id(.:format)      workers#destroy
           clients GET    /clients(.:format)                             clients#index
                   POST   /clients(.:format)                             clients#create
        new_client GET    /clients/new(.:format)                         clients#new
       edit_client GET    /clients/:id/edit(.:format)                    clients#edit
            client GET    /clients/:id(.:format)                         clients#show
                   PATCH  /clients/:id(.:format)                         clients#update
                   PUT    /clients/:id(.:format)                         clients#update
                   DELETE /clients/:id(.:format)                         clients#destroy
              root GET    /                                              clients#index

在 app/views/workers/show.html.erb 我有以下链接:<%= link_to 'Back', client_path(@client) %>

工人的控制者

class WorkersController < ApplicationController
  before_action :set_worker, only: [:show, :edit, :update, :destroy]

  # GET /clients/:client_id/workers
  # GET /clients/:post_id/workers.xml
  def index
    #1st you retrieve the client thanks to params[:client_id]
    client = Client.find(params[:client_id])
    #2nd you get all the workers of this client
    @workers = client.workers

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @comments }
    end
  end

  # GET /clients/:client_id/workers/:id
  # GET /workers/:id.xml
  def show
    #1st you retrieve the client thanks to params[:client_id]
    @client = Client.find(params[:client_id])
    #2nd you retrieve the comment thanks to params[:id]
    @worker = client.workers.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @comment }
    end
  end

  # GET /clients/:client_id/workers/new
  # GET /clients/:client_id/workers/new.xml
  def new
    #1st you retrieve the post thanks to params[:post_id]
    client = Client.find(params[:client_id])
    #2nd you build a new one
    @worker = client.workers.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @comment }
    end
  end

  # GET /posts/:post_id/comments/:id/edit
  # GET /clients/:client_id/workers/:id/edit
  def edit
    #1st you retrieve the post thanks to params[:post_id])
    client = Client.find(params[:client_id])
    #2nd you retrieve the comment thanks to params[:id]
    @worker = client.workers.find(params[:id])
  end

  # POST /client/:client_id/workers
  # POST /client/:client_id/worker.xml
  def create
    #1st you retrieve the post thanks to params[:post_id]
    client = Client.find(params[:client_id])
    #2nd you create the comment with arguments in params[:comment]
    @worker = client.workers.create(worker_params)

    respond_to do |format|
      if @worker.save
        #1st argument of redirect_to is an array, in order to build the correct route to the nested resource comment
        format.html { redirect_to([@worker.client, @worker], :notice => 'Worker was successfully created.') }
        #the key :location is associated to an array in order to build the correct route to the nested resource comment
        format.xml  { render :xml => @worker, :status => :created, :location => [@worker.client, @worker] }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @worker.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /client/:client_id/Workers/:id
  # PUT /client/:client_id/workers/:id.xml
  def update
    #1st you retrieve the post thanks to params[:post_id]
    client = Client.find(params[:client_id])
    #2nd you retrieve the comment thanks to params[:id]
    @worker = client.workers.find(params[:id])

    respond_to do |format|
      if @worker.update_attributes(worker_params)
        #1st argument of redirect_to is an array, in order to build the correct route to the nested resource comment
        format.html { redirect_to([@worker.client, @worker], :notice => 'Worker was successfully updated.') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @worker.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /client/:client_id/workers/1
  # DELETE /client/:client_id/worker/1.xml
  def destroy
    #1st you retrieve the post thanks to params[:post_id]
    client = Client.find(params[:client_id])
    #2nd you retrieve the comment thanks to params[:id]
    @worker = client.workers.find(params[:id])
    @worker.destroy

    respond_to do |format|
      #1st argument reference the path /posts/:post_id/comments/
      format.html { redirect_to(client_workers_url) }
      format.xml  { head :ok }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def worker_params
      params.require(:worker).permit(:first_name, :last_name, :birth_day, :birth_month, :birth_year, :birth_city, :birth_state, :client_id)
    end
end

【问题讨论】:

  • 你能发布你的workers_controller吗?
  • 如果您想从/clients/1/workers 链接回/clients/1,则说明您使用了错误的路径。你应该使用client_path(some_client)
  • Meaga,我如何表示“some_client”?使用实例变量或 id 属性?
  • 只需在show 方法中将client 更改为@client 并使用client_path(@client)
  • 您是否将WorkersController#index 中的局部变量client 更改为@client(实例变量),类似于@Pavan 在#show 操作中建议的内容。问题是局部变量 client 不会被传递给视图,而是会在您离开操作的上下文时被释放,但实例变量将被传递给视图并且可以访问您需要的路由.

标签: ruby-on-rails ruby ruby-on-rails-4 link-to nested-routes


【解决方案1】:

感谢 cmets 中的每个人,我们能够找到答案。我决定将答案组合在一起,以便其他有此问题的人更容易找到此帖子。

正确的链接是:&lt;%= link_to 'Back', client_path(@client) %&gt;

为此,我必须将 WorkersController #show 和 #index 方法更改为以下内容:

class WorkersController < ApplicationController
def index
  #1st you retrieve the client thanks to params[:client_id]
  @client = Client.find(params[:client_id])
  #2nd you get all the workers of this client
  @workers = @client.workers

  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @comments }
  end
end

# GET /clients/:client_id/workers/:id
# GET /workers/:id.xml
def show
  #1st you retrieve the client thanks to params[:client_id]
  @client = Client.find(params[:client_id])
  #2nd you retrieve the comment thanks to params[:id]
  @worker = client.workers.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @comment }
  end
end

本质上,将局部变量 client 更改为实例变量 @client 以便它可以访问。

【讨论】:

    【解决方案2】:

    您想要的网址需要在/clients/ 之后加上:id。您的路线表明/clients/:id 的路径为client_path 而不是clients_path。 (client GET /clients/:id(.:format)clients#show ). 因此,如果您在该 workers#index 页面中有该 ID,则可以将其写为

    &lt;%= link_to 'Back', client_path(@client) %&gt;。交叉检查语法并尝试。

    【讨论】:

    • 感谢 tGeek 的帮助。
    • 根据您答案中的正确语法更新了路线。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-24
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 1970-01-01
    相关资源
    最近更新 更多