简体   繁体   English

polymorphic_path或url_用于自定义控制器名称

[英]polymorphic_path or url_for how customize controller name

I have a situation where I have @challenge and @idea instances from Challenge and Idea model responsively. 我遇到的情况是,我有来自Challenge和Idea模型的@challenge和@idea实例作为响应。

I have one partial which is going to used in many controllers, so based on controllers I want to generate path. 我有一部分要在许多控制器中使用,因此我想基于控制器生成路径。

eg So when I am in IdeasController polymorphic_path([@challenge, @idea]) will generate "/challenges/12/ideas/45" 例如,所以当我在IdeasController中时,polymorphic_path([@ challenge,@idea])将生成“ / challenges / 12 / ideas / 45”

but if I am in any other controller suppose RefinementsController, I want generate path as "challenges/12/refinements/45" 但是如果我在其他任何控制器中都假设使用RefinementsController,则我希望生成路径为“ challenges / 12 / refinements / 45”

How can I generate it using polymorphic_path or url_for 如何使用polymorphic_path或url_for生成它

code: 码:

app/controllers/ideas_controller.rb 应用程序/控制器/ 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

app/controllers/refinements_controller.rb 应用程序/控制器/ 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

app/views/ideas/index.html.erb 应用程序/视图/创意/ 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>

app/views/ideas/show.html.erb 应用程序/视图/创意/ 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>

Although it's not a good practice but if it's only a minor change and rest of your partial is same in all cases then what you do is use some generic variable in your partial. 虽然这不是一个好习惯,但是如果只是很小的更改,而在所有情况下您的局部变量都相同,那么您要做的就是在局部变量中使用一些通用变量。 In your case your polymorphic url depends on the initialized value of second variable ie @idea(as first part challenges/12/ is same) so you can do something like this: 在您的情况下,您的多态网址取决于第二个变量的初始化值,即@idea(因为第一部分Challenges / 12 /是相同的),因此您可以执行以下操作:

polymorphic_path([@challenge,@something_generic])

and now depending on your controllers action you can change @something_generic to make proper url for your form 现在,根据您的控制器操作,您可以更改@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

Update: 更新:

Change your code to this: 将代码更改为此:

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

Since you are using cancancan and have proper filters so @idea and @challenge will be defined automatically in your actions. 由于您使用的是cancancan并且具有适当的过滤器,因此@idea和@challenge将在您的操作中自动定义。

For index.html i think you'll be better of using separate templates but if you still want to use a single template then you can do something like this: 对于index.html,我认为您最好使用单独的模板,但是如果您仍然想使用单个模板,则可以执行以下操作:

app/views/ideas/index.html.erb 应用程序/视图/创意/ 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>

and show.html.erb 和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>

Partial 局部

Without having your partial code here, I'm going to make an assumption that you are calling polymorphic_path inside your partial, hence wanting to change the path as per the controller it's loaded from 在这里没有partial代码的情况下,我将假设您正在partial代码中调用polymorphic_path ,因此希望根据从其加载的控制器更改路径

If you're calling a partial, you have to remember its been designed to be an independent, modular element of your application, and so including @instance variables in your partial will likely be an antipattern 如果要调用部分,则必须记住它被设计为应用程序的独立模块化元素,因此在部分中包含@instance variables可能会成为反模式。

What I would recommend is to populate your partial with local variables , allowing you to populate those accordingly: 我建议使用local变量填充部分变量 ,从而允许您相应地填充这些变量

#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]) %>

-- -

Update 更新

Thanks for your code 感谢您的验证码

You'll be totally better be using the following: 使用以下方法会更好:

#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} %>

This will allow you to call: 这将使您可以致电:

#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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM