模型是否可以使用相同模型的两个关联:通过?

时间:2016-06-03 18:06:33

标签: ruby-on-rails-4 activerecord

我们说我有三种模式:组织,技能和评估。

评估是否可以通过不同的关系属于两个不同的组织

例如,评估可能发生在组织A,但基于属于组织B的技能。

以下是我的模特和协会:

import java.awt.EventQueue;
import java.util.Enumeration;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;

/**
 * @see http://stackoverflow.com/a/5614370/230513
 */
public class Test {

    private static final String TEXT
        = "<html>"
        + "<head></head>"
        + "<body>"
        + "<div align=center id=unique_id>Test</div>"
        + "</body>"
        + "</html>";

    public static void main(String[] args) throws Exception {
        EventQueue.invokeLater(new Test()::display);
    }

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JEditorPane jep = new JEditorPane("text/html", TEXT);
        jep.setEditable(false);
        f.add(jep);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);

        HTMLDocument htmlDoc = (HTMLDocument) jep.getDocument();
        System.out.println(htmlDoc.getElement("unique_id"));
        ElementIterator iterator = new ElementIterator(htmlDoc);
        Element element;
        while ((element = iterator.next()) != null) {
            try {
                printElement(htmlDoc, element);
            } catch (BadLocationException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    private void printElement(HTMLDocument htmlDoc, Element element) throws BadLocationException {
        AttributeSet attrSet = element.getAttributes();
        System.out.println(""
            + "Element: '" + element.toString().trim()
            + "', name: '" + element.getName()
            + "', children: " + element.getElementCount()
            + ", attributes: " + attrSet.getAttributeCount()
            + ", leaf: " + element.isLeaf());
        Enumeration attrNames = attrSet.getAttributeNames();
        while (attrNames.hasMoreElements()) {
            Object attr = attrNames.nextElement();
            System.out.println("  Attribute: '" + attr + "', Value: '"
                + attrSet.getAttribute(attr) + "'");
            Object tag = attrSet.getAttribute(StyleConstants.NameAttribute);
            if (attr == StyleConstants.NameAttribute
                && tag == HTML.Tag.CONTENT) {
                int startOffset = element.getStartOffset();
                int endOffset = element.getEndOffset();
                int length = endOffset - startOffset;
                System.out.printf("    Content (%d-%d): '%s'\n", startOffset,
                    endOffset, htmlDoc.getText(startOffset, length).trim());
            }
        }
    }
}

使用上述内容,我可以获得一个评估组织:

class Organization < ActiveRecord::Base
  has_many :checklists
  has_many :levels, :through => :checklists
  has_many :sections, :through => :levels
  has_many :skills, :through => :sections
  has_many :assessments_using_own_checklists, :through => :skills, :source => :assessments
end

class Skill < ActiveRecord::Base
  belongs_to :section
  has_one :level, through: :section
  has_one :checklist, through: :level
  has_one :organization, through: :checklist
  has_many :assessments
end

class Assessment < ActiveRecord::Base
  belongs_to :skill
  has_one :section, through: :skill
  has_one :level, through: :section
  has_one :checklist, through: :level
  has_one :checklist_owner, through: :checklist, source: :organization
  belongs_to :organization
end

我还可以获得评估的checklist_owner:

Assessment.last.organization # yields organization 1

但是当我尝试在Assessment.last.checklist_owner # yields organization 2 中使用checklist_owner时,该关联似乎忘记使用where。例如,如果我运行:

:through

...这转换为SQL:

Assessment.where(organization: Organization.find(2), checklist_owner: Organization.find(1))

查看SQL如何有两个SELECT "assessments".* FROM "assessments" WHERE "assessments"."organization_id" = 2 AND "assessments"."organization_id" = 1语句?为什么这样做?

1 个答案:

答案 0 :(得分:1)

您是否尝试过使用joins

类似的东西:

Assessment.joins(skill: { section: { level: :checklist } }).where(organization: Organization.find(2), checklists: { organization_id: Organization.find(1) })

我知道它看起来很糟糕,但似乎你从评估到核对表的关系非常复杂。这将照顾到任何奇怪的关系。