【问题标题】:Active record query on Many to many relationship多对多关系的活动记录查询
【发布时间】:2017-05-04 21:06:46
【问题描述】:

我有一个名为 Event 的模型和另一个名为 Product 的模型。一个事件有很多产品,一个产品有很多事件(通过称为Eventproduct 的连接模型)。我正在尝试设计一个查询,该查询将选择在任何情况下都不与另一个事件的当前日期范围匹配的所有产品,因此当用户创建具有日期范围的事件时,它将显示可用的产品,以便同一产品不能同时参加 2 个活动。这可以通过活动记录查询界面实现,还是我需要编写自己的特定 SQL 查询。

我的迁移看起来像:

class CreateProducts < ActiveRecord::Migration
  def change
    create_table :products do |t|
      t.string :make
      t.string :model
      t.integer :wattage
      t.boolean :dmx
      t.decimal :price
      t.timestamps
    end
  end
end


class CreateEvents < ActiveRecord::Migration
  def change
    create_table :events do |t|
      t.datetime :start_date
      t.datetime :end_date
      t.timestamps
    end
  end
end


class AddContactToEvent < ActiveRecord::Migration
  def change
    add_column :events, :name, :string
    add_column :events, :location, :string
    add_column :events, :contact_number, :string
  end
end

class CreateEventproducts < ActiveRecord::Migration
  def change
    create_table :eventproducts do |t|
      t.references :product
      t.references :event

      t.timestamps
    end
    add_index :eventproducts, :product_id
    add_index :eventproducts, :event_id
  end
end

以下是相关模型:

class Event < ActiveRecord::Base
  attr_accessible :end_date, :start_date, :products, :lightings, :name, :location, :contact_number, :product_ids
  has_many :products, :through => :Eventproduct
  has_many :Eventproduct
  validates_presence_of :name, :message => "can't be blank"
  validates_presence_of :location, :message => "can't be blank"
  validates_presence_of :contact_number, :message => "A telephone number is needed so that we can contact you if we have any problems"
  validates_presence_of :start_date, :message => "can't be blank"
  validates_presence_of :end_date, :message => "can't be blank"
end

class Eventproduct < ActiveRecord::Base
  belongs_to :product
  belongs_to :event
  # attr_accessible :title, :body
end


class Product < ActiveRecord::Base
  validates :price, numericality: {greater_than_or_equal_to: 0.01}
    attr_accessible :make, :model, :wattage, :dmx, :price
end

【问题讨论】:

    标签: ruby-on-rails-3 activerecord active-record-query


    【解决方案1】:

    我想出了一个可以帮助您的查询。您必须确定时间范围的条件及其逻辑。

    查询应该类似于

    Product.joins(:events).where("events.start_date <= :start_date", {start_date: Time.now})
    

    where 子句应包含过滤不需要的事件的逻辑。再次,那段代码应该让你开始。因此,要回答您的问题,这是可能的。查看您获得的查询并解决该查询以使条件符合您的需求。另外,看看这个链接,它应该可以帮助您像我一样修改 where 子句: http://guides.rubyonrails.org/active_record_querying.html

    希望对您有所帮助!

    更新:

    您可能需要与 Product.all 一起做一些设置差异以包含那些根本没有事件的产品,因为如果产品在 EventProduct 表中没有事件,则该查询将返回空。它可能效率不高,但它应该根据您的需要工作。

    Product.all - Product.joins(:events).where("condition reversed")
    

    这应该返回所有不符合您条件的产品,包括那些还没有事件的产品。

    【讨论】:

      【解决方案2】:

      试试这个:Product.includes(:Eventproduct).where(eventproducts: { event_id: nil }).group('products.id')。

      注意它是where条件内的表名。另外不要忘记将 Eventproduct 关联添加到您的产品模型中:has_many :Eventproduct

      【讨论】:

      • 他必须包含 EventProduct 否则它将在产品表中查找他没有的 event_id。
      • @antonk 我添加了 hm 关联,但是在控制台中运行命令时,我仍然收到错误,它在产品表中查找事件 ID。
      • @Dean 我一说我的评论就注意到了。我正在考虑一种方法来满足您的要求。
      • @Dean 对不起。查看我的答案的变化(条件)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多