Multiple many to one associations - datamapper

In my app, each Game involves two players, who have different roles. One plays cat, the other plays dog. How can I describe this in Ruby's datamapper?
The documentation only gives examples where the names of the properties match the name of the class, which limits us to one association per class http://datamapper.org/docs/associations.html
I would like my game to have a cat player and a dog player.

The doc by your link has the answer. Read more thoroughly.
class Player
include DataMapper::Resource
end
class Game
include DataMapper::Resource
belongs_to :cat, 'Player'
belongs_to :dog, 'Player'
end
Update: you can use these associations in the Player model if you need
class Player
include DataMapper::Resource
has n, :cat_games, :child_key => [ :cat_id ]
has n, :dog_games, :child_key => [ :dog_id ]
end

Related

Thinking Sphinx Has Many Through Rails

Can you please help me in thinking sphinx?
Relationship:
Continent
has_many :countries
has_many :country_reports, through: :countries, :class_name => "Report"
has_many :publishers, through: :country_reports
Expected Output:
I want to find Continent.first.publishers
Please tell me how to write this in thinking sphinx rails
As I answered on the Thinking Sphinx Google group:
Because you’re searching on publishers, it’s the Publisher index you’ll need to modify to get this to work. I’m presuming a publisher belongs_to :country_report, country report belongs_to :country, and country belongs_to :continent.
If you’re using SQL-backed indices (using the :with => :active_record option), then you’ll want the following in your Publisher index:
has country_report.country.continent_id, :as => :continent_id
If you’re using real-time indices (:with => :real_time), then it’s the same, but you must specify the type as well:
has country_report.country.continent_id, :as => :continent_id, :type => :integer
However, if there’s a has_many or has_and_belongs_to_many instead of belongs_to in that chain of associations from publisher to continent, then it’s a little more complicated. Also, in this case, it might be possible to have more than one continent for a publisher, so we’re dealing with multiple values here.
For SQL-backed indices, a minor change, alter the associations chain:
has country_reports.country.continent_id, :as => :continent_ids
But with a real-time index, it’s better to have a method on the Publisher model that returns the necessary value or values, and then use that in the index:
# in app/models/publisher.rb
def continent_ids
country_reports.collect(&:country).collect(&:continent_id)
end
# in app/indices/publisher_index.rb
has continent_ids, :type => :integer, :multi => true
And then, once you’ve rebuilt your index, you can search as follows (with the attribute being plural if appropriate):
Publisher.search “foo”, :with => {:continent_id => continent.id}
This may work as well (the multiple levels of associations may confuse things though):
continent.publishers.search “foo”

Ruby advanced active record queries across multiple tables

I'm fairly new and am coming across a problem as I progress in the application I'm working on.
I have the following relationships set up
game
belongs_to :challenge
has_many :game_players, through: :playersessions, source: :user
has_many :playersessions
challenge
has_many :phrases
has_many :games
phrase
has_many :playedphrases
has_many :playersessions, through: :playedphrases
playedphrase
belongs_to :playersession
belongs_to :phrase
playersession
has_many :playedphrases
has_many :phrases, through: :playedphrases
All these relationships are working in my program, but I need to start doing some more advanced querying. For instance, I would like to find the remaining phrases. In english it would be "find this Game's Challenge's Phrases and remove the this Game's Playersession's Phrases". I believe the problem lies in the fact that #game.challenge.phrases returns Phrase objects and #game.playersessions must be iterated through to find all the phrase objects.
Any guidance on how to handle this type of query? Please let me know if any other info would help out.
I finally figured out a way to make this work - I don't know if it is the most eloquent ruby, but it works.
def determine_remaining_phrases
remain = #game.challenge.phrases
#playersessions.each do |session|
remain -= session.phrases
end
return remain
end
Basically I needed to iterate through the playersessions and remove the associated phrases each pass through. This leaves me with an array of phrase objects. If someone has a more eloquent answer, please let me know.

Creating a "feed" from multiple rails models, efficiently?

This is a follow up to Creating "feeds" from multiple, different Rails models. In this question, tadman suggests this method of creating a user feed of recent items from three models (Ticket, Post, Report):
#items = [ Ticket, Post, Report ].inject([ ]) do |a, with_class|
a + with_class.find(:all, :limit => 10, :order => 'created_at DESC')
end.sort_by(&:created_at).reverse[0, 10]
He suggests this as a method that will work, but that won't necessarily be the most efficient. He suggests as well than an alternative method would be to "create an index table that's got a polymorphic association with the various records."
I'm really interested in learning more about this alternative solution, it seems both more efficient and more elegant. Can anyone tell me how one would do this? Let's use the same background info from the last question as a base.
What I did once was, have a separate model Feed (feeds_controller) and update it in after_save callbacks to all the interesting models. So for example if you have a model Article, have an after_save callback:
def after_save
feed = Feed.new
feed[:model_name] = 'Article'
feed[:item_id] = id
feed.save
end
then, you can access the feed linearly just like any other model. The computational expense is incurred when saving the the feed, not reading from the feed.
Oh, you can also have Feed has_many :article; has_many :user, has_many :status and so forth, and then :include all those resources in the feed, and render them in views. Hope this makes sense ;-)

Rails 3: problem with as_json in combination with include

I have two models in a 1:n relation. Both are put out in JSON only. Therefore I defined as_json in both models:
class Foo < ActiveRecord::Base
has_many :foos, dependent: :destroy
def as_json options={}
super except: [:created_at, :updated_at, :id, :user_id], include: options[:include]
end
end
class Bar < ActiveRecord::Base
belongs_to :foo
def as_json options={}
super except: [:id, :foo_id, :created_at, :updated_at], include: options[:include]
end
end
Now I request foo's and bar's independently and as_json works as excepted. But in case I request bar's with foo's included the response contains foo's with attributes that should not be there. In fact as_json is not even called.
This seems to be standard behaviour. But how can I turn it off / achive my goal to always use as_json independently, wether include is used or not?
I appreciate every kind of hint, link or answer that helps solving this question.
Thx in advance.
Felix

Problem with relations

Hey I have a problem with the extension of the existing dependency models. Well, according to
between the models are as follows:
I have a User model:
class User <ActiveRecord::Base
has_many :words, :through => :memo_words
has_many :memo_words, :dependent => :destroy
end
class MemoWord
belongs_to :user
belongs_to :word
end
class Word
has_many :translations, :dependent => :destroy
has_many :memo_words, :dependent => :destroy
end
class Translation
belongs_to :word
end
This is a diagram now:
http://img221.imageshack.us/img221/4232/przedik.png
Word model represents a word in one language and the model represents the Translation translation of individual words. I want to resolve the situation when a record in the table and the Word, there is no record Translation (word has no translation). I want to allow for user to add their own translations, but translations done by adding a local (per user). Due to the lack of relationship between Translation and User, the User is not possible to add words. And I question whether a good solution is to add the model UserTranslation:
UserTranslation class
belongs_to :word
belongs_to :user
end
And diagram with situation after change.
http://img851.imageshack.us/img851/7269/75031527.png
Which would have the same functionality as the model of Translation. In practice, I would have to copy the model to UserTranslation Translation by adding only 'belongs_to :user'. Is there a better approach to the problem
I would suggest that in your current scheme consider UserTranslations to be STI for Translations so -
class UserTranslation < Translation
belongs_to :user
end
This way all user translated words will be saved inside "translations" table but with type "user_translations". Then you may make id unapproved by default and build admin side approval functions.
This way, #word.translation would yield either translation or user_translation object.