Rails - 来自同一操作(索引)的多个视图(管理员,常规)

时间:2014-11-03 06:59:48

标签: ruby-on-rails ruby-on-rails-3

我有两个版本的相同索引页面,显示产品列表。 常规视图 - 显示列表 管理员视图 - 显示包含编辑,删除等选项的列表。

索引操作只是使数据库查询并返回该实例变量。 目前,我有相同的索引操作来呈现索引页面。我想将索引操作表单产品重用到管理控制器中。

def index
    @products = Product.all
end

路线:

/product/index  => product#index

/admin/product/index  => product#index

我尝试了prepend_view_path技术[here here How can I intercept rails's template rendering,但在这两种情况下,这总是最终呈现admin / product / index.html.erb文件。

我希望Product#index controller#action呈现:

  

/index.html.erb / product / index

  

/admin/product/index.html.erb for / admin / product / index

有人可以帮助我以优雅的方式完成这项工作,而不是仅为管理员控制器类和产品控制器类编写相同的操作。

PS:我只用了一个星期的红宝石和红宝石在铁轨上。非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

路线上有错误。

/ product / index =>产品#索引

/ admin / product / index =>产品#索引

两者都指向与产品相同的控制器名称。

我会建议这些路线

resources  :admin do 
  resources :product do 
  end
end

resources :product do 
end

通过这样做,您确保您有两个产品Controller。  一个使用Admin :: ProductController 第二个ProductController

管理员视图的admin_product_path 普通视图的product_path

答案 1 :(得分:0)

在你的控制器中,只需渲染你想为用户服务的视图,我的意思是:

ProductsController
def index
  # ...
  render 'index'
end

Admin::ProductsController
def index
  # ...
  render 'products/index'
end

答案 2 :(得分:0)

在处理 Rails 6 应用程序时,我遇到了这个挑战。

我有两种类型的用户:客户管理员。我正在使用 Devise gem进行身份验证。我希望客户产品视图与管理员视图不同。

控制器中,我已经有一个app/controllers/admins目录,用于管理员 Devise 配置。

这是我的做法

首先,使用products名称空间为Admins admins视图定义新的路由

namespace :admins do
  resources :products do
  end
end

注意:这将影响管理员的路径/ URL。假设products_path不会是admins_products_path

然后,在控制器中,将products_controller.rb添加到app/controllers/admins目录中:

class Admins::ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update, :destroy]

  # GET /products
  # GET /products.json
  def index
    @products = Product.all
  end

  # GET /products/1
  # GET /products/1.json
  def show
  end

  # GET /products/new
  def new
    @product = Product.new
  end

  # GET /products/1/edit
  def edit
  end

  # POST /products
  # POST /products.json
  def create
    @product = Product.new(product_params)

    respond_to do |format|
      if @product.save
        format.html { redirect_to admins_product_path(@product), notice: 'Product was successfully created.' }
        format.json { render :show, status: :created, location: admins_product_path(@product) }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /products/1
  # PATCH/PUT /products/1.json
  def update
    respond_to do |format|
      if @product.update(product_params)
        format.html { redirect_to admins_product_path(@product), notice: 'Product was successfully updated.' }
        format.json { render :show, status: :ok, location: admins_product_path(@product) }
      else
        format.html { render :edit }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /products/1
  # DELETE /products/1.json
  def destroy
    @product.destroy
    respond_to do |format|
      format.html { redirect_to admins_products_url, notice: 'Product was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Only allow a list of trusted parameters through.
    def product_params
      params.require(:product).permit(:name, :sku, :short_description, :full_description)
    end
end

注意:记录使用Admins模块的ProductsController名称空间以及createupdatedestroy操作中的修改路径

最后,在视图中,在app/views/admins/products目录中添加与Admins产品关联的视图。

注意:您可能必须修改视图中的路径以与admin产品的路由相对应。说,管理员产品show视图将是admins_product_path(product),而不是productproduct_path(product)

使用cells宝石是一种更清洁的方法。这消除了重复代码的需要,并且在您需要定义最多3个或更多角色的视图时非常方便。您可以在这里阅读有关如何使用它的更多信息:Object-Oriented Views in Rails

仅此而已。

我希望这会有所帮助