【问题标题】:Activerecord "where" condition for Array attributeArray 属性的 Activerecord“where”条件
【发布时间】:2017-08-01 03:32:01
【问题描述】:

我的模型 course.rbpre_courses 是一个数组。

class Course < ActiveRecord::Base
  serialize :pre_courses, Array
end

现在我想通过 Activerecord 或原始 SQL(我正在使用 MySQL)检查是否存在 coursepre_course,例如 Course.where("pre_courses INCLUDEs self.id")。

有什么办法吗?

【问题讨论】:

  • 试试Course.where(" '#{self.id}' = ANY (pre_courses)")
  • 试试这个Course.includes(:pre_courses).where.not(pre_courses: {id: nil} ") Course.includes(:pre_courses).where.not(pre_courses: {id: nil} ").find(self.id)
  • 你的第一步应该是用一个单独的表替换serialize
  • 带有LIKE 的查询对于很多列往往非常慢并且难以优化。一旦我需要通过带有LIKE 的序列化数据列进行查询,我会考虑另一种数据结构:可能是JSON 或规范化表结构。

标签: mysql ruby-on-rails ruby activerecord


【解决方案1】:

序列化数组只是db中的一个字符串,所以尝试使用LIKE,例如:

Course.where("pre_courses LIKE ?", "% #{self.id}\n%")

请注意,序列化数组在每个项目之前添加一个空格,之后添加一个新行,因此在插值字符串之前添加了空格,在末尾添加了 \n

【讨论】:

  • 如果 21 在 YAML 化数组中,但您正在搜索 2,会发生什么情况?
  • @muistooshort 那个具体情况应该不是问题,因为\n2 之后;但它适用于以2 结尾的任何数字。所以数字前必须加一个空格;我会更新答案。谢谢。
【解决方案2】:

听起来pre_course实际上是一个普通的course,一个course可以有很多pre_courses,一个pre_course可以属于很多courses。自引用has_many through 关系是可能的,与将数据序列化为数组相比,它可以让您更灵活地处理数据。

你需要一个加入模型,我会打电话给CoursePreCourse。它将包含course_idpre_course_id 列。 pre_course_id 将是 courses 表中记录的外键。

class CreateCoursePreCourses < ActiveRecord::Migration[5.1]
  def change
    create_table :course_pre_courses do |t|
      t.references :course, foreign_key: true
      t.references :pre_course, foreign_key: { to_table: :courses }

      t.timestamps
    end
  end
end

class CoursePreCourse < ApplicationRecord
  belongs_to :course
  belongs_to :pre_course, class_name: 'Course'
end

class Course < ApplicationRecord
  # A straight-forward has_many :through association for a course that has_many :pre_courses
  has_many :course_pre_courses
  has_many :pre_courses, through: :course_pre_courses

  # A little coercion is necessary to set up the association as a pre_course that has_many :courses
  has_many :pre_course_courses, class_name: 'CoursePreCourse', foreign_key: :pre_course_id
  has_many :courses, through: :pre_course_courses
end

现在您可以使用course.pre_courses 检索任何coursepre_coursescourses。如果您想查看course 是否是其他coursespre_course,它是pre_course.courses。同样,您可以使用course.pre_courses &lt;&lt; pre_coursepre_course.courses &lt;&lt; coursecourse 添加到另一个coursepre_courses

你有没有说过一个词多次失去意义?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多