尝试在应用程序布局中加载视图并在每个页面上调用其操作

Trying to load a view in application layout and calling its action on every page

我正在尝试加载包含产品类型列表的视图。我需要在每个页面上显示视图。但是在其他页面中没有调用该操作,请告诉我我哪里出错了,并提出任何替代方案。

index.html.erb

<h1>Listing the types of products</h1>
<% content_for :sidebar do %>
<% @types.each do |type| %>             
    <li><%= link_to type.name, product_type_path(type)%>    <!-- go to product_type controller show action-->
    <%= link_to "Edit", edit_product_type_path(type) %> <!-- go to product_type controller edit action -->
    <%= link_to "Delete", product_type_path(type) , method: :delete, data: { confirm: "Are U Sure?" }%>     <!-- go to product_type controller delete action and a pop to confirm the action -->
    </li>
<% end %>

<h3><%= link_to "New Type Of Product", new_product_type_path %></h3>
<h3><%= link_to "All Types of Products", products_path %></h3> <!-- All types of products listed for admin's ease -->
<% end %>

这是我正在使用的应用程序布局。

Application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <%= render 'layouts/title' %>
    <%= render 'layouts/rails_defaults'%>
    <%= render 'layouts/shim' %>
  </head>

  <body>
    <aside><%= yield: sidebar %></aside>
    <%= render 'layouts/header' %>
    <%= render 'layouts/flash' %>
      <div class="container">
        <%= yield %>
      </div>
    <%= render 'layouts/footer' %>
  </body>
</html>

如您所见,我正在使用 yield: sidebar ,但它无法正常工作,从某种意义上说,如果我转到不同的页面,则不会调用操作索引。

Product_types 控制器

class ProductTypesController < ApplicationController

    def index
        @types = ProductType.all        #to get all the records to an instance variable(array in the case) lasts only until the scope lasts. Since the is defined in index, it lasts only till you are using the index view
    end

    def new
        @type = ProductType.new         #to create a new record into the respective model
    end

    def show
        @type = ProductType.find(params[:id])       #Finding the type of product click on
        @products = Product.where(value: @type.value)       #finding all the products whose value field is same as the type of product value(primary key) 
    end

    def create
        @type = ProductType.new(type_params)        #type params defined below in private class 
        if @type.save                               #save the product created
            redirect_to root_url                    #and redirect to root
        else                                        #if doesnt save and error occurs
            render 'new'                            #error occurs and render 'new' view
        end
    end

    def edit
        @type = ProductType.find(params[:id])
    end

    def update
        @type = ProductType.find(params[:id])
        if @type.update(type_params)                #update the params
            redirect_to root_url                    #if updated redirect to root
        else                        
            render 'edit'                           #else if error occurs render 'edit' view again
        end
    end

    def destroy
        ProductType.find(params[:id]).destroy       #destroy the record
        redirect_to root_url                        #redirect to root 
    end

    private

        def type_params
            params.require(:product_type).permit(:name,:value)      #used to only permit type and value thorugh request(to prevent hacking) used in create and update action above
        end
end

每当我跳转到另一个页面时,都不会调用该操作。 请提出替代方案。

content_for / yield 适用于仅由当前操作调用的当前视图。因此,如果其他页面的视图中没有 content_for :sidebar,则它们不会有侧边栏。如果您直接包含在 content_for 中,它仍然不会执行所需的任何额外控制器逻辑。

如果您想要可重复使用的内容,而不是可重复使用的 "space"。

,请使用像您的 layouts/header 这样的帮助程序或部分内容

对于您不想只在部分中做的事情,而且不仅在直接 Ruby 中(使用 content_tag 等),您可以将部分和帮助程序结合起来。

class ApplicationHelper # Or any other helper
  def products_sidebar
    products = Product.where(show_on_sidebar: true).order(:popularity) # Or whatever you like
    render partial: "shared/products_sidebar", locals: {products: products}
  end
end

shared/_products_sidebar.html.erb(肯定会考虑其他模板引擎)

<div id="products_sidebar">
    <% products.each do |product| %>
        <div><%=product.name%></div> <!--whatever you want it to look like-->
    <% end %>
</div>

然后在你的索引中,直接调用即可,不会依赖于当前正在处理的action/controller

<body>
    <aside><%= products_sidebar %></aside>