Self-referential symmetric many-to-many - ruby-datamapper

I'm quite stumped trying to model self-referential, many-to-many, symmetrical entity using Datamapper:
I want to keep track of compatibility of various software releases I'm tracking:
class SoftwareRelease
include DataMapper::Resource
property :id, Serial
property :software_release_type_id, Integer
property :version, String
belongs_to :software_release_type
has n, :compatibilities, child_key: [ :source_id ]
has n, :compatible_releases, self, through: :compatibilities, via: :target
end
class SoftwareReleaseType
include DataMapper::Resource
property :id, Serial
property :name, String
property :short_name, String
has n, :software_releases
end
class Compatibility
include DataMapper::Resource
belongs_to :source, 'SoftwareRelease', key: true
belongs_to :target, 'SoftwareRelease', key: true
end
A given software release 'a.b.c' can have a type of 'hardware platfrom foo', while a given software release 'd.e.f' can have a type of 'hardware platform bar'.
To establish compatibility between the software release in the above code, I must perform 2 adds
release_a_b_c.compatible_releases << release_d_e_f
release_d_e_f.compatible_releases << release_a_b_c
That's kinda ugly.
I'd love to be able to do just one add and have a symmetric relationship established. I can obviously wrap 2 pushes with an instance method in SoftwareRelease, but that feels like I'm sweeping the ugliness under a rug. Any ideas for an elegant solution?
Much obliged,
Pawel
PS
Long time ago, active-record had acts_as_network plugin which did something similar. Haven't been able to find anything in the DM world.

I don't think there is anything in DM or any of its plugins to do what you want, but I would like to posit that writing an instance method to create both one-way relations is in fact fairly elegant and I wouldn't consider it "sweeping the ugliness under the rug" at all.
Part of the power of implementing object relations in classes is that the programmer gets to extend those classes in meaningful ways by creating instance methods inside the class. You have a need for a symmetrical relationship between objects, so writing that simple instance method is meaningful and self-documenting. And there is no risk of side effects or inappropriate calls because it is a public method of that specific class.
I'm not really saying anything new, here, but I think your solution is perfectly acceptable. Frankly, I would rather see relatively rare use cases pushed into the programmer's domain, rather than clutter up the DataMapper code. I don't need one of those big fat Victorinox pocket knives with every conceivable tool. :)

Related

ActiveModelSerializers Polymorphic Json

Been wrestling with trying to get polymorphic serializers working and testing data via rspec. Just upgraded to 0.10+
I found this post, which makes a lot of sense, and does give me a entry into generating the serializations, however, when doing it for polymorphs, I never get the type and id properly named (expecting to see asset_id and asset_type nested)
{:id=>1,
:label=>"Today I feel amazing!",
:position=>0,
:status=>"active",
:media_container_id=>1,
:asset=>
{:id=>4
Test ActiveModel::Serializer classes with Rspec
class MediaSerializer < ApplicationSerializer
attributes :id,
:label,
has_one :asset, polymorphic: true
end
I noticed that the tests dont even seem to properly add the polymorphic identifiers either (ie asset_id, asset_type -- or in the test case imageable_id, imageable_type)
https://github.com/rails-api/active_model_serializers/commit/045fa9bc072a04f5a94d23f3d955e49bdaba74a1#diff-c3565d7d6d40da1b2bf75e13eb8e6afbR36
If I go straight up MediaSerialzer.new(media) I can poke at the .associations, but I cant seem to get them to render as if I was generating a full payload
From the docs
https://github.com/rails-api/active_model_serializers
serializer_options = {}
serializer = SomeSerializer.new(resource, serializer_options)
serializer.attributes
serializer.associations
Im pretty sure Im missing something/doing something wrong - any guidance would be great.
Thanks
It isn't easy to get the effect you are looking for, but it is possible.
You can access the hash generated by the serializer by overriding the associations method.
class MediaSerializer < ApplicationSerializer
attributes :id,
:label,
has_one :asset, polymorphic: true
def associations details
data = super
data[:asset] = relabel_asset(data[:asset])
data
end
def relabel_asset asset
labelled_asset = {}
asset.keys.each do |k|
labelled_asset["asset_#{k}"] = asset[k];
end
labelled_asset
end
end
I learnt alot about ActiveModelSerializer to get the hang of this! I referred to Ryan Bates' podcast on the topic:
http://railscasts.com/episodes/409-active-model-serializers
In there he describes how you can override the attributes method and call super to get access to the hash generated by the serializer. I guessed I could do the same trick for the associations method mentioned in your post. From there it takes a little bit of Ruby to replace all the keys, but, if I have understood correctly what you require, it is technically possible.
Hope that helps!

Neo4j.rb returns models with incorrect class for nodes with multiple labels

I have two ActiveNode models:
class Company
include Neo4j::ActiveNode
end
and
class Entity
include Neo4j::ActiveNode
end
They correspond to the labels "Entity" and "Company", which are attached to the same node. So, a node and be an entity and a company.
In my console, when I attempt the following query:
Entity.where(entity_id: 1).first
It returns a Company object:
#<Company uuid: entity_id: 1>
I don't want that. If I ask for an entity, I want an entity returned. The Entity model have different methods defined than the Company model. Is there anyway I can enforce the correct behavior? It seems pretty pretty counter intuitive that it behaves in this way.
I am using neo4j 3.0 and neo4j.rb 7.0.3
This is a good point. If both labels could be matched, it should use the one for the class which was used to do the find.
I'm curious about your modeling, though. Can a Company node ever not be an Entity or vice versa? Or is, for example, a Company always a kind of an Entity? If so, you might want to use inheritence:
class Entity
include Neo4j::ActiveNode
end
class Company < Entity
# No need to include Neo4j::ActiveNode
end
But it's partially a question of if it makes sense for Company nodes to inherit the behavior/logic of Entity

How to specify Node Label in Neo4jrb

I get a trouble about customize node label in Neo4jrb.
class Core::Product
include Neo4j::ActiveNode
id_property :id
property :name
property :code
property :stock_quantity, type: Integer
property :sale_price, type: Float
property :last_update, type: DateTime
end
When I create new node, it will has label as Core::Product. I want it to be Product instead.
According this post It seem that _classname property could resolve my problem but I have no idea how to implement it.
Any ideas?
Co-maintainer of Neo4j.rb here and author/responsible party for _classname. _classname is a very legacy option at this point, a holdover from when some DB responses didn't include node labels or relationship types. You can override automatic label assignment by calling self.mapped_label_name = in your model.
class Core::Product
include Neo4j::ActiveNode
self.mapped_label_name = 'Product'
# etc,...
end
You'll also want to be aware that the auto-location of association models won't work correctly, so instead of this:
has_many :out, :products, type: 'HAS_PRODUCT'
You'll need to do this:
has_many :out, :products, model_class: 'Core::Product', type: 'HAS_PRODUCT'
We have an open issue, https://github.com/neo4jrb/neo4j/issues/753, that discusses it. I namespace my models to organize code but want my labels to omit them, so I'd love a configuration option that handles this for me.
FOLLOW-UP
I just merged https://github.com/neo4jrb/neo4j/pull/790 into master. It lets you tell the gem to ignore module names when creating labels. I'm going to put it to work in some code this week but if you'd like to test it out, we always love feedback.

UML relationships - dashed line vs solid line

What is the difference between these 2 relationships?
Edit: Also if you could provide a simple code example illustrating the difference, that would be really helpful!
I'm trying to give simple examples of the two types of lines.
In the first diagram, the solid line shows an association:
If the classes were declared in Java, this would be like ClassA storing a reference to ClassB as an attribute (it could be passed in to the constructor, created, etc.). So, you might see something like:
public class ClassA {
ClassB theClassB = ...
...
}
In the second diagram, it shows a dependency:
A dependency is much weaker than an association. To quote from UML Distilled:
With classes, dependencies exist for various reasons: One class sends a message to another; one class has another as part of its data; one
class mentions another as a parameter to an operation. [...] You use dependencies
whenever you want to show how changes in one element might alter other elements.
Again, using Java, a couple of examples exist: an argument of type ClassB is passed to a method, or a method declares a local variable of type ClassB:
public class ClassA {
...
public void someMethod(ClassB arg1) {...}
...
public void someOtherMethod() {
ClassB localReferenceToClassB = ...
}
...
}
Other ways ClassA could depend on ClassB without having an association (not an exhaustive list):
ClassB has a static method that ClassA calls
ClassA catches exceptions of type ClassB
Whenever ClassB is modified, ClassA must also be modified (e.g., some logic is shared)
Your question gave me a good chance to learn myself, here is what I found -
Association: Ownership of another type (e.g. 'A' owns a 'B')
//#assoc The Player(A) has some Dice(B)
class Player {
Dice myDice;
}
Dependency: Use of another type (e.g. 'C' uses a 'D')
//#dep The Player(C) uses some Dice(D) when playing a game
class Player {
rollYahtzee(Dice someDice);
}
Here's a crisp ref I found - Association vs. Dependency
This webpage says enough I think
The following text comes from it, but should be enough to understand the difference.
So basically the solid line is an association and the dashed/dotted line is a dependency.
Associations can also be unidirectional, where one class knows about
the other class and the relationship but the other class does not.
Such associations require an open arrowhead to point to the class that
is known and only the known class can have a role name and
multiplicity. In the example, the Customer class knows about any
number of products purchased but the Product class knows nothing about
any customer. The multiplicity "0..*" means zero or more.
A dependency is a weak relationship between two classes and is
represented by a dotted line. In the example, there is a dependency
between Point and LineSegment, because LineSegment's draw() operation
uses the Point class. It indicates that LineSegment has to know about
Point, even if it has no attributes of that type. This example also
illustrates how class diagrams are used to focus in on what is
important in the context, as you wouldn't normally want to show such
detailed dependencies for all your class operations.
Since my reputation is only 8 I can't place the images itself, but they can still be found on the webpage I mentioned at the start.
[EDIT]
I don't have code examples right here, but how I personally would explain it is as simple as a car and a door.
When a car has a door (or more) it's just a car
Car --- has a --> Door
But when you have a door which can be opened the door class will have a function like
public void openDoor(){
this.open();
}
To use the function above the car will have to create an instance of the door
Class Car(){
Door door1 = new Door();
door1.open();
}
In this way you have created a dependency.
So the solid line is just pointing an object(1) to another object(2), but when you start using the object(1) it becomes a dependency.
Okay, since you didn't accept the first answer; let me try.
Arrow 1: A normal association
UML has different types of lines and arrows. Above is the simple association arrow, that means that one class can have a link to the other class. Below I will explain each type WITH code examples.
In the first example, you can see that there isn't really specified who knows who (who is the owner of the relationship). An animal can know the human and the human can know the animal. It's not specified and thus not really helpful for the programmer.
In the second example, the artist can have a guitar. Because there is an arrow and there isn't one on the other side, we know that the guitar doesn't know the artist. A guitar is an object that can totally exist on its own and doesn't need anybody.
In the third example, you see a marriage. Really simple; the husband knows the wife and the wife knows her husband. In our situation, the husband has only one wife and vice versa.
How do we accomplish this usually in code?
class Husband{
Wife bestWomanInTheWorld;
public Husband(Wife theWife){
this.bestWomanInTheWorld = theWife;
}
}
Because the husband always needs a wife, we put the required relationship in the constructor. Because an artist can have a guitar, we would leave the constructor empty like this:
class Artist{
List<Guitar> guitars;
public Artist(){
}
public AddGuitarToCollection(Guitar newGuitar){
Guitars.Add(newGuitar);
}
}
So, that's how we accomplish this in code (most of the time!). You won't usually need different types of lines and arrows if you are new to programming. Keep it simple.
Arrow 2: Dependency
Okay, so we know about normal associations which we will use most of the time. But when will we use the 'dependency' arrow? Well, lets define a dependency (wikipedia):
Dependency is a weaker form of bond which indicates that one class depends on
another because it uses it at some point in time. One class depends on
another if the independent class is a parameter variable or local variable of
a method of the dependent class. This is different from an association, where
an attribute of the dependent class is an instance of the independent class.
Sometimes the relationship between two classes is very weak. They are not
implemented with member variables at all. Rather they might be implemented as
member function arguments.
If there is a connection, relation, association etc. that requires to be present, to the classA to work; it's a dependency. Example: Husband needs the Wife to exist. A car needs a wheel to be a car (and drive). A car factory needs a car class to make an object from it. Your RSSNewsItem class needs an XMLReader class to do anything.
When to use which?
Well, this is the only valid question in my eyes; since google shows alot of valid answers to your question. Try to never use a dependency in a class diagram because it usually means that you aren't specific enough. Always aim for associations, realisations etc. Only use realisations (in my opinion) if there is a required need to use an other class without maintaining a relationship. Example; Utility classes (like the XMLReader).
If you have any questions after reading this full explanation, feel free to ask. :-)
Dotted line indicates dependency to (in the direction of the arrow). Assuming you have assembled your source code neatly into separate files and headers for each class
- the give away is simply that the code includes the line #include ClassB.h.
HOWEVER The fact of the matter is that all class relationships (generalisation, realisation, composition, aggregation, association etc) all inherit the dependency relationship. For this reason I never use dotted arrows when documenting code. Where possible I would aim to document the relationship in more specific terms eg. diamonds, triangles etc. If I don't know the exact relationship my starting point is a solid line with arrows (an association, with (implicit) dependence).
Notwithstanding this the dotted arrow notation can be useful in other aspects of UML modelling eg. showing dependencies to requirements in Use Case analysis for example.
NOTE The Thought Police would have us reduce coupling & dependencies between classes by using interfaces (pure virtual classes) as far as practical.
Whilst pure virtual classes offer the prospect of multiple inheritance and tightest coupling of all between classes as is possible. Interface classes have the advantage that they are made entirely out of dark matter and so totally invisible to the police. With this in mind it is possible to write c++ code with apparently zero coupling between classes -which they love because they never really did understand all those funny looking symbols anyway.
dotted mean implements (an interface)
solid means extends (a base class)

Ember.js with Rails accepts_nested_attributes_for and polymorphic has_many/belongs_to

On the Rails API side I have the following 2 models:
class Grower < ActiveRecord::Base
has_many :addresses, as: :addressable
accepts_nested_attributes_for :addresses
end
class Address < ActiveRecord::Base
belongs_to :addressable, polymorphic: true
end
as well as a Growers controller which returns and can create/update Growers with embedded Addresses attributes. I also have an Addresses controller with proper routing so that Addresses can be viewed/created/updated for a specific Grower. The latter is more of an "in-case", and I'm not sure I'll be needing to return/update/create addresses as a separate payload.
I am starting to try and piece together an Ember app that would allow me to view/edit/create a Grower at the same time as its Address(es). Can anyone point me to an existing real or sample app that does this? I will be posting my code as I go along, but I already have an idea of some areas where I will be running into trouble:
Rails returns/expects nested params named addresses_attributes. Ember, I am sure, doesn't use that convention. What's the best approach of resolving this?
Because of the polymorphic association (objects other than Grower can be addressable), on the API/Address side, to get the correct belongs_to object, Rails uses addressable_id in conjunction with addressable_type. In this example the addressable_type would be "Grower", and the addressable_id would be the grower_id value. How would one go about translating that on the Ember side?
UPDATE:
I got it to work at least a couple different ways. My preferred solution, at least for this particular case, is in the answer section.
Here is a sample of code based #yuяi's strategy that worked well for me:
App.Post = DS.Model.extend
comments: DS.hasMany('comment')
App.PostSerializer = DS.ActiveModelSerializer.extend( DS.EmbeddedRecordsMixin,
attrs:
comments: {embedded: 'always'}
keyForAttribute: (attr) ->
if attr == "comments"
"comments_attributes"
else
#_super(attr)
)
This solution worked well with Ember 1.6.1 and Ember Data 1.0.0-beta.8.2a68c63a.
I found a couple ways to get it done, but the final approach doesn't require any changes on the Rails/API side.
On the client (Ember) side:
I added the addresses hasMany property to the App.Grower model. I also mapped it on the RESTAdapter to what's expected from the API, by setting the key for addresses to addresses_attributes.
I added the grower (for now - will change to addressable once I have other addressable models) belongsTo property on App.Address. It's not really required for what I'm doing, but it might be useful in the future.
I set the addresses on the RESTAdapter to be embedded: 'always'.
On the App.GrowersEditController, I just do a model.save (transaction.commit), and the child addresses are automatically saved via the API call.
On the App.GrowersAddController, I use the App.Address.createRecord and App.Grower.createRecord methods using the user-entered Grower and Address data. Then I use the pushObject method to append the Address to the Grower, and then call a save on the Grower (commit on transaction). Again, the address data gets submitted and saved automatically.