mongodb - "Not equal" named scope in rails with Mongoid -
i have 2 models content
, contenttype
. in content model can do:
def get_all_content_except_poking_message content.all.where(:name.ne => "no forking, poking") end
now, trying apply scope on contenttype. in content model again:
# associations belongs_to :content_type def get_all_content_except_certain_content_type(content_type) content.all.where(:content_type.name.ne => content_type) end
but error suggests wrong syntax apply scope on association's field.
what right way apply scope on association's fields in model?
also using has_scope gem. can apply same filter in controller too? like:
@contents = apply_scopes( if params[:type] @content_type = contenttype.find_by_slug(params[:type]) @content_type.contents.all else content.all.where (:content_type.name.ne => "blogs") end )
update
for clarification, here irb output:
irb(main):020:0> contenttype.all(:name=>"blogs").count => 1 irb(main):023:0> content.last.content_type.name => "blogs" irb(main):024:0> content.all.where(:content_type => {:name => {'$ne' => "blogs"}}).count => 0 irb(main):026:0> content.all.count => 4
the quick answer mongodb server query operates on single collection. there no join crosses collections. querying on contents collection, specifying field in content_types collection.
you can use embedding put 2 models 1 collection, , query can work against embedded document (sub)field.
i can supply more detail if like, past current astonishment.
addendum requested without embedding:
important note: accessing data multiple collections require multiple queries, @ least 1 query per collection.
the following example based on extract post, modifications work want methods. "not equals" query makes use of knowledge of association implementation quick answer now, link structure pretty obvious inspection. note actual moped queries mongodb show in appropriate rails log.
i'm not familiar particulars of plataformatec/has_scope. mongoid has own scopes should investigate, i'm willing when there.
app/models/content_type.rb
class contenttype include mongoid::document field :name, type: string has_many :contents end
app/models/content.rb
class content include mongoid::document field :name, type: string belongs_to :content_type def self.get_all_content_except_poking_message content.where(:name.ne => "no forking, poking") end def self.get_all_content_except_certain_content_type(content_type_name) # 2 queries - 1 each contenttype , content content_type = contenttype.where(:name => content_type_name).first content.where(:content_type_id.ne => content_type.id) end end
test/unit/content_test.rb
require 'test_helper'
class contenttest < activesupport::testcase def setup content.delete_all contenttype.delete_all end test "not equal blogs" blogs = contenttype.create(:name => "blogs") tweets = contenttype.create(:name => "tweets") blogs.contents << content.create(:name => "no forking, poking") tweets.contents << content.create(:name => "kilroy here") assert_equal 2, contenttype.count assert_equal 2, content.count puts "all content_types: #{contenttype.all.to_a.inspect}" puts "all contents: #{content.all.to_a.inspect}" puts "get_all_content_except_poking_message: #{content.get_all_content_except_poking_message.to_a.inspect}" puts "get_all_content_except_certain_content_type(\"blogs\"): #{content.get_all_content_except_certain_content_type("blogs").to_a.inspect}" end end
rake test
run options: # running tests: [1/1] contenttest#test_not_equal_blogsall content_types: [#<contenttype _id: 51ded9d47f11ba4ec1000001, name: "blogs">, #<contenttype _id: 51ded9d47f11ba4ec1000002, name: "tweets">] contents: [#<content _id: 51ded9d47f11ba4ec1000003, name: "no forking, poking", content_type_id: "51ded9d47f11ba4ec1000001">, #<content _id: 51ded9d47f11ba4ec1000004, name: "kilroy here", content_type_id: "51ded9d47f11ba4ec1000002">] get_all_content_except_poking_message: [#<content _id: 51ded9d47f11ba4ec1000004, name: "kilroy here", content_type_id: "51ded9d47f11ba4ec1000002">] get_all_content_except_certain_content_type("blogs"): [#<content _id: 51ded9d47f11ba4ec1000004, name: "kilroy here", content_type_id: "51ded9d47f11ba4ec1000002">] finished tests in 0.046370s, 21.5657 tests/s, 43.1313 assertions/s. 1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
for simple case, can "simplify" departing strict relational normalization, e.g., add "content_type_name" field content string values "blogs".
but take advantage of mongodb, shouldn't hesitate embed.
hope helps.
Comments
Post a Comment