简体   繁体   中英

Rails - Query One Model from within a Different Model with a has_many & belongs_to relationship

I'm not entirely clear on how to query a models data from within a different model in Rails. The models have a has_many & belongs_to relationship. The 2 models are "Gear" and "line_item". Gear has_many line_items and LineItem belongs_to Gear.

What I'm trying to do is query all the line_items in the database that belong to a Gear object that have a NULL or Blank cart_id (this is one of the fields) and then calculate it's availability. Since in this case the Gear is rented out at certain dates and times that are stored in a line_item (start_date, end_date, start_hour, end_hour) ..Having not done a lot of advanced quering in Ruby I Googled around and now I'm not sure if how I should use

Enumerable in the Gear Model with something like this:

line_items.inject(0) {|line_item| line_item.where('line_items.cart_id' => NULL }

Or if I could use a scope in the Gear Model like this:

scope :availablegear, lambda { includes(:line_items).where('line_items.cart_id' => nil) }

I know the syntax on both is probably not correct so I could use some direction on what to use and how to use it.

Thanks.

MY Project is using Rails 3.2.0, Ruby 1.9.4 & MySQL

EDIT with Suggested Answer

class Gear < ActiveRecord::Base
  attr_accessible :title, :size, :price, :sub_category_id, :user_id, :image, :image_a, :image_b, :image_c, :image_d, :image_e, :image_f, :image_g, :image_h, :image_i, :remote_image_url, :color, :year, :latefee, :cancellation, :minrental, :policy, :about, :address, :city, :state, :zip, :country, :latitude, :longitude, :gmaps
  ...some code omitted for brevity
  has_many :line_items
  scope :availablegear, joins(:line_items).where(:line_items => {:cart_id => nil})
  ...some code omitted for brevity

end

Now when I boot up Rails console and I do ag = Gear.find(4) and then do g.availablegear I get the following error: NoMethodError: undefined method `availablegear' for #

I think the query you're looking for is

Gear.joins(:line_items).where(:line_items => {:cart_id => nil})

You can put it in a scope in the Gear class:

class Gear< ActiveRecord::Base
  scope :available, joins(:line_items).where(:line_items => {:cart_id => nil})
end

You can find some more help in the Rails Query Guide (see 11.3 for joining with conditions).

If you're trying to get line items back:

class Gear < ActiveRecord::Base
  has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :gear

  scope :available, where(:cart_id => nil)
end

Then if you have a gear, you can call

gear.line_items.available

which will return line items that belong to gear and have no cart_id .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM