【问题标题】:Rails: Association between Category, Subcategory, and LawyerRails:类别、子类别和律师之间的关联
【发布时间】:2017-01-09 22:13:42
【问题描述】:

我有大量的律师、类别和子类别列表。

提示(如果我的关联正常,您可以知道)

  1. 在类别表中,我不想看到类别表中的列引用子类别。
  2. 在子类别表中,我不想在子类别表中看到引用类别的列。
  3. 并非所有类别都有子类别。即有些没有如图所示的子类别。
  4. 我有 2 个单独的表单来创建类别和子类别。
  5. 我将 category_id 和 subcategory_id 作为外键添加到了我的律师表中。这样我就可以在创建时从律师表格中选择律师在图像中所属的类别或子类别。
  6. 另请注意:可以在任何时间、任何一天为没有子类别的类别创建子类别,以及已经有一些子类别的类别下的新子类别,并在其下放置律师。李>
  7. 该图像是我目前拥有的索引/主页的复制品,至少在上述第 6 条每天任何时间生效之前,我希望使用循环来实现此视图。

对我正在尝试做的事情的图示理解:

这是我在 3 个模型之间的关系

class Lawyer < ActiveRecord::Base
  belongs_to :category
  belongs_to :subcategory
end

class Category < ActiveRecord::Base
  has_many :lawyers
end

class Subcategory < ActiveRecord::Base
  #belongs_to :category #Do I want "category_id" in Subcategories Table?
  has_many :lawyers
end

问题

对于我给出的提示,我对这 3 个模型的关联是否正常?这是 相当混乱。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 associations model-associations


    【解决方案1】:

    您不需要Subcategory 模型/表,特别是如果它们具有相同的列。你的categories 表应该有一个parent_id 列。当一个类别具有指向另一个类别记录的parent_id 值时,它就是一个子类别。带有NULLparent_id 的类别是顶级类别。

    示例

    class Lawyer < ActiveRecord::Base
      belongs_to :category
    end
    
    class Category < ActiveRecord::Base
      has_many :lawyers
    
      # This is called a self referential relation. This is where records in a 
      # table may point to other records in the same table.
      has_many :sub_categories, class_name: "Category", foreign_key: :parent_id
    
      # This is a scope to load the top level categories and eager-load their 
      # lawyers, subcategories, and the subcategories' lawyers too.
      scope :top_level, -> { where(parent_id: nil).include :lawyers, sub_categories: :lawyers }
    end
    

    注意:您应该创建一个迁移以将parent_id 列添加到类别表中。您可以删除子类别表。

    现在创建一些类别(我假设有一个 name 列):

    cat = Category.create name: "Corporate and Commercial Law"
    subcat = Category.new name: "Corporate Tax", parent_id: cat.id
    subcat.lawyers << Lawyer.find_by_name("Sabina Mexis")
    subcat.save
    

    目录示例:

    <% Category.top_level.each do |cat| %>
      <%= cat.name %>
      <% cat.sub_categories.each do |subcat| %>
        <%= subcat.name %>
        <%= subcat.lawyers.each do |laywer| %> 
          <%= lawyer.name %>
        <% end %>
      <% end %>
    <% end %>
    

    以上是一个简化的例子。希望对您有所帮助。

    更新

    要增强您的表单以允许您创建子类别并分配其父类别,请使用填充有 top_level 类别 ID 的选择菜单:

    <%= form_for Category.new do |f| %>
      <%= f.text_field :name %>
      <%= f.select :parent_id, options_from_collection_for_select(Category.top_level, :id, :name) %>
      <%= f.submit %>
    <% end %>
    

    如果不熟悉,请查看 options_from_collection_for_select 的文档。它所做的是构建一个选择菜单,其中 category:id 作为值,它们的 :name 作为菜单中的文本。确保将:parent_id 添加到强参数中,以允许通过params[:category] 进行质量分配。

    laywer 错误只是我的示例代码中的错字,现在已修复。

    【讨论】:

    • 完美。干净整洁+1
    • @AfolabiOlaoluwaAkinwumi 用另一个例子更新了答案。
    • @AfolabiOlaoluwaAkinwumi 由于lawyers 是一个数组,您必须遍历它们并打印出每个名称。请参阅更新后的示例。
    • @Jake id 列通常是整数。
    • 在帖子控制器中处理帖子 CRUD
    猜你喜欢
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2019-04-19
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    相关资源
    最近更新 更多