Rails在Model方法中加入Query

时间:2015-03-05 16:42:54

标签: ruby-on-rails activerecord

我正在构建一个市场应用程序。我想定义一个列表的条件到期并从网站上删除。

在我的列表模型中,我有以下内容。这样就可以了。

def self.not_expired 
  where('(updated_at >= ? or user_id = ?) and inventory > ?', Date.current - 30.day, 24, 0)
end

然后在我在控制器中的索引方法中,我有@listings = Listing.not_expired,在我的视图中,我有一个循环,并显示这些列表。

在我的模型中,我想添加一个OR条件,它是User模型中的一个字段。卖家可以勾选一个方框,要求我们隐藏他们的网站列表。在用户模型中,我有一个名为hidelistings的布尔字段。列表和用户模型与user_id结合。

如何在上述方法中添加联接以说明以下内容

def not_expired
   where(same as above) OR listing.user.hidelistings == "f"
end

以上语法不起作用。我正在使用SQLite。

1 个答案:

答案 0 :(得分:1)

class User < ActiveRecord::Base
  has_many :listings
end

class Listing < ActiveRecord::Base
  belongs_to :user
end

@listings = Listing.not_expired

第一个解决方案

class Listing < ActiveRecord::Base
  belongs_to :user

  scope :listable, ->{ 
    joins("INNER JOIN users
           ON users.id = listings.user_id
           AND users. hidelistings = 'f'") 
  }

  def self.not_expired
    listable.where('(updated_at >= ? OR user_id = ?) AND inventory > ?', Date.current - 30.day, 24, 0)
  end
end

这将生成以下SQL:

SELECT "listings".* FROM "listings" INNER JOIN users ON users.id = listings.user_id AND users. hidelistings = 'f' WHERE ((listings.updated_at >= '2015-02-03' ... ))

第二种解决方案

class Listing < ActiveRecord::Base
  belongs_to :user

  def self.not_expired
    joins(:user).where("((listings.updated_at >= ? OR user_id = ?) AND inventory > ?) OR users.hidelistings = 'f')", Date.current - 30.day, 2)
  end
end

这将生成以下SQL:

SELECT "listings".* FROM "listings" INNER JOIN "users" ON "users"."id" = "listings"."user_id" WHERE (((listings.updated_at >= '2015-02-03' OR user_id = 2) OR users.hidelistings = 'f'))

如果您愿意,可以使用AREL重构条件以提高可读性。