polymorphic_path或url_for如何自定义控制器名称

时间:2014-08-10 06:21:47

标签: ruby-on-rails

我有一种情况,我有来自Challenge和Idea模型的@challenge和@idea实例。

我有一个部分将在许多控制器中使用,所以基于控制器我想生成路径。

e.g 所以,当我在IdeasController中时,polymorphic_path([@ challenge,@ aida])将生成" / challenge / 12 / ideas / 45"

但如果我在任何其他控制器中假设RefinementsController,我想生成路径为" challenge / 12 / refinements / 45"

如何使用polymorphic_path或url_for

生成它

代码:

应用程序/控制器/ ideas_controller.rb

class IdeasController < ApplicationController
  before_action :authenticate_user!
  load_and_authorize_resource :challenge
  load_and_authorize_resource :idea, through: :challenge

  def index
  end

  def show
  end
end

应用程序/控制器/ refinements_controller.rb

class RefinementsController < ApplicationController
  before_action :authenticate_user!
  load_and_authorize_resource :challenge, parent: true
  load_and_authorize_resource :idea, through: :challenge, parent: false

  def index
    @ideas = @ideas.refined
    render 'ideas/index'
  end

  def show
    render 'ideas/show'
  end
end

应用程序/视图/思想/ index.html.erb

<div class="ideas">
  <% @ideas.each do |idea| %>
    <div class="idea">
      <div class="title">
        <%= link_to idea.title, polymorphic_path([@challenge, idea]) %>
      </div>
    </div>
  <% end %>
</div>

应用程序/视图/思想/ show.html.erb

<div class="idea">
  <div class="title">
    <%= link_to idea.title, polymorphic_path([@challenge, @idea]) %>
  </div>
  <div class="descriptio">
    <%= @idea.description %>
  </div>
</div>

2 个答案:

答案 0 :(得分:0)

虽然这不是一个好习惯但是如果它只是一个小的改变而你的部分的其余部分在所有情况下是相同的,那么你所做的是在你的部分中使用一些通用变量。在你的情况下,你的多态url取决于第二个变量的初始值,即@idea(作为第一部分挑战/ 12 /是相同的) 所以你可以这样做:

polymorphic_path([@challenge,@something_generic])

现在,根据您的控制器操作,您可以更改@something_generic以为您的表单制作正确的网址

class IdeasController < ApplicationController
  def new
    @challenge = Challenge.find(params[:challenge_id])
    @something_generic = @challenge.ideas.build
  end
end

class RefinementsController < ApplicationController
  def new
    @challenge = Challenge.find(params[:challenge_id])
    @something_generic = @challenge.refinements.build
  end
end

<强>更新

将您的代码更改为:

class IdeasController < ApplicationController
  before_action :authenticate_user!
  load_and_authorize_resource :challenge
  load_and_authorize_resource :idea, through: :challenge

  def index
  end

  def show
    @something_generic = Idea.find(params[:id])
  end
end

class RefinementsController < ApplicationController
  before_action :authenticate_user!
  load_and_authorize_resource :challenge, parent: true
  load_and_authorize_resource :idea, through: :challenge, parent: false

  def index
    @something_generic = Refinement.find(params[:id])
    render 'ideas/index'
  end

  def show
    @something_generic = Refinement.find(params[:id])
    render 'ideas/show'
  end
end

由于您正在使用cancancan并拥有适当的过滤器,因此将在您的操作中自动定义@idea和@challenge。

对于index.html,我认为您最好使用单独的模板,但如果您仍想使用单个模板,则可以执行以下操作:

应用程序/视图/思想/ index.html.erb

<div class="ideas">
  <% @ideas.each do |idea| %>
    <div class="idea">
      <div class="title">
        <% if controller_name == "ideas" %>
          <%= link_to idea.title, polymorphic_path([@challenge, idea]) %>
        <% else %>
          <%= link_to idea.title, polymorphic_path([@challenge, @something_generic]) %>
        <% end %>
      </div>
    </div>
  <% end %>
</div>

和show.html.erb

<div class="idea">
  <div class="title">
    <%= link_to @idea.title, polymorphic_path([@challenge, @something_generic]) %>
  </div>
  <div class="description">
      <%= @idea.description %>
  </div>
</div>

答案 1 :(得分:0)

<强>部分

如果没有你的partial代码,我会假设你在你的部分内部调用polymorphic_path,因此想根据它加载的控制器改变路径

如果您正在调用部分内容,则必须记住它已被设计为应用程序的独立modular元素,因此在您的部分中包含@instance variables可能是#app/controllers/ideas_controller.rb Class IdeasController < ApplicationController def show @challenge = Challenge.find params[:challenge_id] if params[:challenge_id].present? @idea = Idea.find params[:id] end end #app/views/ideas/show.html.erb <%= render "shared/partial", locals: {challenge: @challenge, child: @idea} %> #app/views/shared/_partial.html.erb <%= link_to "Test", polymorphic_path([challenge, child]) %> 3}}

我建议使用antipattern填充您的部分内容,以便相应地填充这些内容:

#app/views/ideas/index.html.erb
<%= render "ideas/item", collection: @items, as: :item, locals: {challenge: @challenge} %>

#app/views/ideas/show.html.erb
<%= render "ideas/item", object: @item, as: :item, locals: {challenge: @challenge} %>

-

<强>更新

感谢您的代码

使用以下内容会更好:

#app/views/ideas/_idea.html.erb
<div class="idea">
  <div class="title">
    <%= link_to idea.title, polymorphic_path([challenge, idea]) %>
  </div>
  <% if action_name =="show" %>
    <div class="descriptio">
      <%= idea.description %>
    </div>
  <% end %>
</div>

这将允许您致电:

{{1}}