【问题标题】:Rails: Show only items belonging to current modelRails:仅显示属于当前模型的项目
【发布时间】:2013-12-27 04:45:40
【问题描述】:

我有一个 Documents 控制器、模型和视图以及一个 DocumentTypes 控制器、模型和视图。一个文档 has_and_belongs_to_many DocumentTypes 和一个 DocumentType has_and_belongs_to_many Documents。我在文档索引模板上有一个表单,在其中添加新文档时,我将 document_type_id 设置为您从下拉列表中选择的任何文档类型。看起来是这样的:

<%= form_for Project.new, :html => { :multipart => true } do |f| %>
    <%= select_tag "document[document_type_id][]", options_from_collection_for_select(DocumentType.find(:all), "id", "title") %>
<% end %>

接下来我要做的只是在文档类型显示页面上仅列出分配给当前文档类型的文档。我目前只有这个:

// Controller
def show
    ...
    @documents = Document.find(:all)
end

// View
<% @documents.each do |document| %>
    ...
<% end %>

我不完全确定在添加新文档时 document_type_id 设置是否正确,所以这很可能是我的问题。我尝试过使用.where,例如:@documents = Document.where(:document_type_id =&gt; 1),但在浏览器中查看时只会给我一个空白列表。

我需要在这里做什么?

【问题讨论】:

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


    【解决方案1】:

    这是一个最小的传递示例。 它还演示了一种很好的快速方法,可以使用测试来玩弄代码,直到你得到你想要的:

    > rails new so20794896
    > cd so20794896
    > rails g scaffold documents
    > rails g scaffold document_types
    > rails g migration create_document_types_documents document_id:integer document_type_id:integer
    > rake db:migrate
    

    编辑 app/models/document.rb

    class Document < ActiveRecord::Base
      has_and_belongs_to_many :document_types
    end
    

    编辑 app/models/document_type.rb

    class DocumentType < ActiveRecord::Base
      has_and_belongs_to_many :documents
    end
    

    编辑 test/models/document_test.rb

    require 'test_helper'
    
    class DocumentTest < ActiveSupport::TestCase
      test "find by document type" do
        one = documents(:one)
        doc_type = document_types(:two)
        one.document_types << doc_type
        one.save!
    
        found_docs = DocumentType.find(doc_type.id).documents
        assert_equal one, found_docs.first
        assert_equal 1, found_docs.length
      end
    end
    

    然后通过以下方式运行测试:

    > rake test TEST=test/unit/document_test.rb 
    

    并查看 log/test.log 以获取此问题的查询,例如:

    SELECT "document_types".* FROM "document_types" INNER JOIN "document_types_documents" 
      ON "document_types"."id" = "document_types_documents"."document_type_id" 
      WHERE "document_types_documents"."document_id" = ?  [["document_id", 980190962]]
    

    【讨论】:

    • 感谢您的详细回答。我的联想与您在上面已经显示的完全一样。我尝试了测试,但它并没有真正给我任何我需要的东西。我现在基本上需要弄清楚为什么在使用&lt;% @document_type.documents.each do |document| %&gt;test&lt;% end %&gt; 之类的东西时,它根本没有列出“测试”。我假设添加新文档时没有正确保存 document_type_id。
    • 我在添加新文档时使用它来选择文档类型:
    • document_type_id 不是document 模型的属性,那么为什么不直接将选择命名为document_type_id 并直接获取该参数呢?我建议进行控制器测试,以确保控制器操作正确选择并使用正确的参数,然后您可以查看日志以确保从视图发送该参数。
    【解决方案2】:

    我认为你没有很好地建立关系。 如果您的文档属于文档类型,那么关系应该像

    Document belongs_to document_type
    

    并将 document_type_id 添加到文档表中。

    那么您的查询将起作用。

    如果你真的想要 has_and_belongs_to_many 关系,那么你必须设置中间 table.like

    Document has_and_belongs_to_many document_types through: document_type_relation
    DocumentType has_and_belongs_to_many documents through: document_type_relation
    

    DocumentTypeRelation 将具有 document_id 和 document_type_id 然后您可以查询 DocumentTypeRelation 以查找具有特定文档类型的所有文档。

    【讨论】:

    • 我确实有一个 DocumentTypesDocuments 表。它看起来像这样:class AddDocumentTypesDocumentsTable &lt; ActiveRecord::Migration def up create_table :document_types_documents do |t| t.integer :document_type_id t.integer :document_id end end def down drop_table :document_types_documents end end
    • 抱歉,修改为连接表的样子。
    • 那么如果您想查找分配给当前文档类型的文档,只需找到该文档类型即可。说 doc_type = DocumentType.find(1),然后使用 doc_type.documents 。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    相关资源
    最近更新 更多