代码之家  ›  专栏  ›  技术社区  ›  vinhboy

通过关联属于

  •  123
  • vinhboy  · 技术社区  · 16 年前

    Question 那个 Choice 从 选择 belongs_to :question, through: :answer 执行此操作。

    class User
      has_many :questions
      has_many :choices
    end
    
    class Question
      belongs_to :user
      has_many :answers
      has_one :choice, :through => :answer
    end
    
    class Answer
      belongs_to :question
    end
    
    class Choice
      belongs_to :user
      belongs_to :answer
      belongs_to :question, :through => :answer
    
      validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
    end
    

    我得到了

    NameError未初始化常量 User::Choice

    当我试着做的时候 current_user.choices

    如果不包括

    belongs_to :question, :through => :answer
    

    但我想用它因为我想 validates_uniqueness_of

    7 回复  |  直到 9 年前
        1
  •  58
  •   stephencelis    16 年前

    一个 belongs_to :through 选择。你最好缓存 question_id 在 Choice validates_uniqueness_of 很容易出现种族状况)。

    如果您多疑,请将自定义验证添加到 这证实了答案是 匹配,但听起来不应该让最终用户有机会提交会导致这种不匹配的数据。

        2
  •  361
  •   Renra    14 年前

    您还可以委派:

    class Company < ActiveRecord::Base
      has_many :employees
      has_many :dogs, :through => :employees
    end
    
    class Employee < ActiveRescord::Base
      belongs_to :company
      has_many :dogs
    end
    
    class Dog < ActiveRecord::Base
      belongs_to :employee
    
      delegate :company, :to => :employee, :allow_nil => true
    end
    
        3
  •  107
  •   jaredsmith    7 年前

    只是使用 has_one belongs_to 在你的 :through ,就像这样:

    class Choice
      belongs_to :user
      belongs_to :answer
      has_one :question, :through => :answer
    end
    

        4
  •  4
  •   Eric Hu    14 年前

    我的方法是创建一个虚拟属性,而不是添加数据库列。

    class Choice
      belongs_to :user
      belongs_to :answer
    
      # ------- Helpers -------
      def question
        answer.question
      end
    
      # extra sugar
      def question_id
        answer.question_id
      end
    end
    

    这种方法非常简单,但需要权衡。它需要铁轨来装载 answer 从数据库,然后 question . 稍后可以通过预先加载所需的关联(即。 c = Choice.first(include: {answer: :question})

    有一个特定的时间和地点选择,我认为这个选择是更好的原型。除非我知道它是用于不常见的用例,否则我不会将它用于生产代码。

        5
  •  1
  •   Adam Tanner    16 年前


    这个问题有很多答案,其中一个是用户的选择。

    这就是你要找的吗?

    我想用这样的线条来做一个模型:

    class User
      has_many :questions
    end
    
    class Question
      belongs_to :user
      has_many   :answers
      has_one    :choice, :class_name => "Answer"
    
      validates_inclusion_of :choice, :in => lambda { answers }
    end
    
    class Answer
      belongs_to :question
    end
    
        6
  •  1
  •   MZaragoza Tushar Walzade    9 年前

    所以你不能有你想要的行为,但你可以做一些感觉像这样的事情。你想做的 Choice.first.question

    我过去做过的事情是这样的

    class Choice
      belongs_to :user
      belongs_to :answer
      validates_uniqueness_of :answer_id, :scope => [ :question_id, :user_id ]
      ...
      def question
        answer.question
      end
    end
    

    选择

        7
  •  -1
  •   Michael Melanson    16 年前

    这个 has_many :choices 创建名为 choices choice . 尝试使用 current_user.choices 相反。

    ActiveRecord::Associations 有关 has_many 魔法。