【问题标题】:Single Table Inheritance with btn-group on create form在创建表单上使用 btn-group 进行单表继承
【发布时间】:2014-04-22 06:41:05
【问题描述】:

我一直试图围绕这个单表继承示例展开思考。我了解它背后的概念,但我不确定通过阅读网络上的其他帖子和本网站上的如何使其适用于我的示例。我使用 STI 是因为我有两种类型的项目——公共项目和私人项目。它们背后的逻辑是相同的,它们存储在数据库中的数据将是相同的,无论是公共的还是私有的。我只是打算在未来为用户实施一些授权和角色,这些授权和角色会根据项目是公共的还是私有的而略有不同。所以我的问题是,还需要哪些步骤才能完成这项工作......到目前为止,我已经:

1) 通过迁移向项目添加了 type_column...我的项目模型是

项目.RB

class Project < ActiveRecord::Base
  has_many :users
  has_many :versions, dependent: :destroy
  validates :title, presence: true, length: { maximum: 100 }
  validates :background, presence: true
  validates :user_id, presence: true

  default_scope -> { order('created_at DESC') }
end

2) 我为 PublicProjects 和 PrivateProjects 创建了单独的类...这些模型是:

PUBLIC_PROJECT.RB

class PublicProject < Project
end

PRIVATE_PROJECT.RB

class PrivateProject < Project
end

所以现在我想知道在我的控制器中需要重新考虑什么(我想保留单个 Projects 控制器)......然后还有什么需要在我的“新”表单视图中进行更改。非常感谢您对可以完成这项工作的代码的逐步帮助。控制器/视图文件是:

PROJECTS_CONTROLLER.RB

class ProjectsController < ApplicationController
  before_filter :signed_in_user, only: [:create, :new, :edit, :update]

  def new
    @project = Project.new
  end

  def show
     @project = Project.find(params[:id])
     @user = User.where(:id => @project.user_id).first
  end

  def index
    @projects = Project.paginate(page: params[:page])
  end

  def create
    @project = current_user.projects.build(project_params)
    if @project.save
      flash[:success] = "Welcome to your new project."
      redirect_to @project
    else
      render 'new'
    end
  end

  def edit

  end

  def update
    @project = Project.find(params[:id])
    if @project.update_attributes(params[:project])
      flash[:success] = "Project Created"
      redirect_to @project
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "Project destroyed"
    redirect_to users_path
  end

  private

    def project_params
      params.require(:project).permit(:title, :background)
    end

end

NEW.HTML.ERB(带表格的新项目视图)

<% provide(:title, 'New Project') %>
<h1>Create a new project</h1>

<div class="row-fluid">
  <div class="col-md-5 no-pad offset3">

    <%= bootstrap_form_for @project do |f| %>

      <%= render 'shared/error_messages', object: f.object %>

      <%= f.text_field :title %>

      <%= f.text_area :background %>

      <div class="row-fluid">
        <div class="no-pad col-md-6">
          <h5>Is this project public or private?</h5>
          <div class="btn-group">
            <button type="button" class="btn btn-default"><%= image_tag "globe.png" %> Public</button>
            <button type="button" class="btn btn-default"><%= image_tag "lock.png" %> Private</button>
          </div>
          <script>
          $(".btn-group > .btn.btn-default").click(function(){
              $(".btn-group > .btn.btn-default").removeClass("active");
              $(this).addClass("active");
          });
          </script>
        </div>
        <div class="col-md-6">
          Some static graphics
        </div>
      </div>

      <br clear="all"><br/>
      <%= f.submit "Create your project", class: "btn btn-lg btn-primary" %>
    <% end %>
  </div>

</div>

最后,我看到了一些进入路由文件的 STI 示例(尽管我看到不经常推荐这样做)。但以防万一:

ROUTES.RB

ProductionApp::Application.routes.draw do
  resources :users
  resources :sessions, only: [:new, :create, :destroy]

  resources :projects do
    resources :versions
  end

  # get "static_pages/home"
  # get "static_pages/help"
  # get "static_pages/about"
  #The original routes above map to...
  root  'static_pages#home'
  match '/signup',  to: 'users#new',            via: 'get'
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'
  match '/help',    to: 'static_pages#help',    via: 'get'
  match '/about',   to: 'static_pages#about',   via: 'get'
  match '/contact', to: 'static_pages#contact', via: 'get'
end

非常感谢您的帮助,

【问题讨论】:

    标签: ruby-on-rails forms ruby-on-rails-4 form-for single-table-inheritance


    【解决方案1】:

    我不确定身份验证,但您可以创建一个类型字段来告诉您项目是公共的还是私有的,而不是使用额外的公共和私有类,例如 is_public。

    另一种选择是使用enum release in rails 4 - 非常简单直接。这是我的首选,但您需要使用最新版本的 rails。

    【讨论】:

    • 嗨 Ryan,'is_public' 类型字段不会在数据库中留下很多空值吗?我被警告要避免这种情况并使用单表继承来做到这一点......我不熟悉枚举......我使用的是 rails 4.0.4。但它看起来很有趣......在STI上使用这样的东西有什么好处(&有没有任何缺点......从我所有的研究来看,STI似乎是解决这个问题的方法,但我意识到枚举非常新的)。感谢您的回复
    • 我猜如果您打算为私有/公共项目添加特定功能,那么 STI 是您可以扩展功能的方式,否则我会为简单起见。
    • 是的,唯一的区别在于未来的角色和权限(所有用户都可以成为公共项目的合作者……只有受邀用户可以成为私人项目的合作者等)。不过,您不太确定如何通过 STI 进行操作,是吧?
    • 经过深思熟虑...我认为您可能是正确的。如果公共项目和私人项目之间的唯一区别是用户访问和各种角色授权......最好将其视为标志。我只是使用了 is_private?按照您的建议键入字段...即使它并不真正对应于有关 STI 的原始问题,我会将您的答案标记为正确,因为它是一种更好的方法。谢谢,
    猜你喜欢
    • 2011-04-30
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2010-09-17
    • 2013-04-01
    • 1970-01-01
    • 2011-08-29
    相关资源
    最近更新 更多