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

时间:2017-09-07 15:02:08

标签: html ruby-on-rails model-view-controller action bootstrapping

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

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&lt; 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

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

1 个答案:

答案 0 :(得分:1)

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

如果您想要可恢复的内容,请使用您的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>

然后在你的索引中,你可以调用它,它不会依赖于当前正在处理的动作/控制器。

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