Have foreign_key on mongoid - mongoid

Well I'm have a PerformerSource and MonthlyEarning documents which has a field called performer_id
class PerformerSource
....
field :performer_id,:type => Integer
....
....
end
class MonthlyEarning
....
field :performer_id,:type => Integer
....
....
end
Now all I want to set a has_many relationships between the two documents with performer_id in mind i.e
performer_source has_many monthly_earnings
monthly_earning belongs_to performer_source
I think the following isn't allowed in Mongoid because apparently when I set the relationships
it just does not return anything
But if it does then please let me know

Apparently this work so the idea was to have relations through performer_id field present in both document so all that is need is
to set this
class PerformerSource
....
field :performer_id,:type => Integer
....
....
has_many :earnings ,:class_name => "MonthlyEarning",:primary_key => :performer_id,:foreign_key => :performer_id
end
class MonthlyEarning
....
field :performer_id,:type => Integer
....
....
belongs_to :performer,:class_name => "PerformerSource",:primary_key => :performer_id,:foreign_key => :performer_id
end
The way it works over here is the :primary_key i.e(performer_id) when firing the request through association
This is exactly what I want

Related

Mongoid query with where clause on an association of an embeded document

I have a Rails app using Mongoid with the classes User, ContractAgreement and ContractVersions.
The relationships are the following: User embeds ContractAgreement, and ContractAgreement belong to ContractVersions, like so:
User:
class User
include Mongoid::Document
include Mongoid::Stateful
include Mongoid::Timestamps
[...]
embeds_many :contract_agreements
ContractAgreement:
class ContractAgreement
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :user
belongs_to :contract_version
field :date_of_agreement, type: DateTime
ContractVersion
class ContractVersion
include Mongoid::Document
include Mongoid::Timestamps
field :version, type: String
field :description, type: String
field :status, type: String
has_one :post, autosave: true
has_one :post, autosave: true
#has_many :contract_agreements
As you can see, #has_many :contract_agreements is commented out as Mongoid didn't like the association to an embeded document.
Is there a way of getting the list of Users that have agreed to a specified contract?
I've tried both doing $elemMatch all the way:
[64] pry(main)> reload!;
u = User.all.select{|u| u.contract_agreements.count > 0}.first ;
cv = u.contract_agreements.first.contract_version ;
User.where(contract_agreements: {'$elemMatch' => {contract_version: {'$elemMatch' => {_id: cv._id}}}}).count
Reloading...
=> 0
As well as the compressed single query notation:
[64] pry(main)> reload!;
u = User.all.select{|u| u.contract_agreements.count > 0}.first ;
cv = u.contract_agreements.first.contract_version ;
User.where("contract_agreements.contract_version._id" => cv._id).count
Reloading...
=> 0
I know the contract version id I am asking for exists since I explicitly select a user that has one.
Is such a query even possible or do I need to de-embed ContractAgreement? If it is possible, what am I doing wrong?
Referring to the foreign key worked:
[73] pry(main)> reload!;
u = User.all.select{|u| u.contract_agreements.count > 0}.first ;
cv = u.contract_agreements.first.contract_version ;
User.where("contract_agreements.contract_version_id" => cv._id).count
Reloading...
=> 1

Elastic Search equivalent of "Scoping (Scalar Fields)" in sunspot/solr

I'm exploring various options for a search engine for our rails-app/data. I was able to make sunspot/solr work and am currently exploring ElasticSearch as an alternative but couldn't get the same thing(scoping/filtering) to work under ES.
I would like to filter/scope objects as described in the "Scoping" section in 'https://github.com/sunspot/sunspot'.
I have an active record class 'Product'.
class Product < ActiveRecord::Base
...
include Tire::Model::Search
include Tire::Model::Callbacks
tire.mapping do
indexes :name, :type => :string
indexes :categories do
indexes :id, :type => :integer
end
end
end
Once I imported products into ES,
the following query works and gives results
Product.tire.search { query { string '*', default_operator: "AND", default_field: "name" } }.results
How do I get products of a particular category given a category id ?
Product.tire.search { query { string '*', default_operator: "AND", default_field: "name" }; filter(:term, 'categories.id' => 38) }.results
I'm basically looking for the tire equivalent for the following sunspot call:
Product.search do
with(:category_ids, 38)
end
with the following in the Product class
searchable :auto_index => true, :auto_remove => true do
text :name
integer :category_ids, :multiple => true do
self.categories.map &:id
end
end

mongoid, embedy_many, simple_form

i m looking for a way to manage multiple embedded objects in a form.
found a solution for formtastic by bowsersenior
Formtastic with Mongoid embedded_in relations
but i wasnt able to do the same for simple_form
formtastic:
= semantic_form_for #team do |form|
= #team.players.each do |player|
= form.inputs :for => [:players, player] do |player_form|
= player_form.input :name
best regards
sample
class Team
include Mongoid::Document
field :name, :type => String
embeds_many :players
end
class Player
include Mongoid::Document
embedded_in :team, :inverse_of => :players
field :name, :type => String
field :active, :type=> Boolean # checkboxes
end
Not sure if this would work but you might want to try something like this:
= simple_form_for #team do |form|
= f.input :name
= f.simple_fields_for #team.players do |player_form|
= player_form.input :name
Just keep in mind that you will have to create a new player in the team before the form will show up.
In your controller(controller):
def new
#team = Team.new
8.times { #team.players.new } #for 8 players
end

cakephp - has many through not saving

I have the following has many through relationship
Alert AlertsElement Search
id id id
name alert_id link
search_id
ordering
Here are my models
class Alert extends AppModel {
var $name = 'Alert';
var $hasMany = array('AlertsElement');
class AlertsElement extends AppModel {
var $name = 'AlertsElement';
var $belongsTo = array('Alert','Search');
class Search extends AppModel {
var $name = 'Search';
var $hasMany = array('AlertsElement');
Here is my test code I am using to do a save -
$d = array();
$d['Alert']['id'] = 1976;
$d['Search']['id'] = 107;
$d['AlertsElement']['ordering'] = 2;
$this->Alert->create();
$this->Alert->saveAll($d);
I get this error -
Cannot use a scalar value as an array [CORE/cake/libs/model/model.php, line 1696]
and a row entry in alertselement with the order but the foreign keys set to 0
Any ideas ?
Thanks, Alex
In order to save a hasMany relationship with saveAll, the hasMany-associated model data (in this case, $d['AlertsElement']) needs to be an indexed array of associative arrays, thus:
$d = array(
'Alert' => array(
'id' => 1976
),
'AlertsElements' => array(
0 => array(
'ordering' => 2
)
)
);
$this->Alert->saveAll($d);
Note that the associative array, consisting of the 'ordering' key and its value, has been shifted down into an indexed array. This is the required format for saving hasMany-associated data in a single saveAll operation, because this format expands gracefully whether you want to save one or ten associated records.
Refer to the Cake manual on saving related model data for more info.
I got here looking for a solution to this question. Not to contradict Daniel, the book says that when you use a hasMany through relationship (which is what Alex is using), you can save all three records with a single saveAll call, but you do it from the joining table's model like this:
$data = array(
[Student] => Array
(
[first_name] => Joe
[last_name] => Bloggs
)
[Course] => Array
(
[name] => Cake
)
[CourseMembership] => Array
(
[days_attended] => 5
[grade] => A
)
);
$this->CourseMembership->saveAll($data);
Unless I've misread the book, that example should create the Student, Course, and joining CourseMembership records. That said, I have yet to be able to get it to work as documented. I'm passing in an id for the Course as I'm using an existing Course, but it doesn't create the Student or the CourseMembership record.
Any more feedback appreciated.

Datamapper Clone Record w/ New ID

class Item
include DataMapper::Resource
property :id, Serial
property :title, String
end
item = Item.new(:title => 'Title 1') # :id => 1
item.save
item_clone = Item.first(:id => 1).clone
item_clone.save
# => <Item #id=1 #title="Title 1" ...
This does "clone" the object as described but how can this be done so it applies a different ID once the record is saved, e.g.
# => <Item #id=2 #title="Title 1" ...
clone is going to give you an object copy, which isn't really what you want - you want to just duplicate the record in the db, correct? The way I have done this with DM in the past is like so:
new_attributes = item.attributes
new_attributes.delete(:id)
Item.create(new_attributes)
You can also do it in one line:
Item.create(item.attributes.merge(:id => nil))

Resources