M2M relationship or 2 FKs? - mysql

Which of the following structures would be preferable:
# M2M
class UserProfile(models.Model):
...
groups = models.ManyToManyField(Group)
class Group(models.Model):
...
or -
# 2 FKs
class UserProfile(models.Model):
...
class Group(models.Models):
...
class GroupMember(models.Model):
user = models.ForeignKey(UserProfile)
group = models.ForeignKey(Group)
Which would be better?

You also can combine these 2 variants using through option
groups = models.ManyToManyField(Group, through='GroupMember')
What do you mean by better? Usually you don't need to create intermediate model (except the case when you have to store extra data).
ManyToManyField does his job perfectly, so don't write its functionality by yourself.

The two are essentially the same. When you do a M2M Django automatically creates a intermediary model, which is pretty much exactly like your GroupMember model. However, it also sets up some API hooks allowing you to access the Group model directly from the UserProfile model, without have to mess with the intermediary model.
You can get the same hooks added back by using through as #San4ez explains, but you've only made things more complicated. Creating a custom through model is only beneficial if you need to add additional fields to the relationship. Otherwise, stick with the default.
Long and short, #1 is better, only because it's exactly the same as #2, but simpler and with no extraneous code.

Related

What are the terms for writing classes in these fashions?

Let's say I have write transformers (e.g. data presentation layer) in such ways that the usage looks like these (using PHP syntax):
A: $userTransformer can be used for different users, kind of like a helper.
$userTransformer->transform($user) // Outputs user data for a webpage
B: $userTransformer is specifically for one user.
$userTransformer->transform() // Same user output
Are there terms describing the ways these transformer classes are designed? A doesn't have any dependency during instantiation, whereas B requires $user to be instantiated. Personally, I prefer B, and I'm trying to look up some literature regarding this.
In the language of UML, consider the difference between dependency and association.
Dependency:
$userTransformer->transform($user) // user is just a method argument
Association:
$userTransformer->transform() // user is a class field
There are two forms of association: aggregation and composition. Personally, when designing class relationships, I think in terms of "strength of relationships" where:
dependency < aggregation < composition

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

Multiple types for each record in Neo4j.rb

I have a database currently represented as a set of YAML files (one record per file). I would like to port it into Neo4j. Each record has a property "type" which stores an array of types. I would like to have a module (that includes ActiveNode) for each type. Each node object would then extend the modules corresponding to its types. The only way I can think of to implement this with neo4j.rb is to generate a class for each existing combination of types and include the corresponding type modules in the class. Is there some better way to accomplish this?
More concrete examples might help. Is there a natural hierarchy to the types?
Class hierarchy for multiple labels has been supported for a while, but I just put in some changes to the master branch in the last couple of days to make it work more smoothly. You should be able to do something like this:
class Person
include Neo4j::ActiveNode
end
class Author < Person
end
class Collaborator < Person
end
class Software
include Neo4j::ActiveNode
end
class Application < Software
end
class Library < Software
end
If you did ChildType.create it would create a node with both the ParentType and ChildType labels. If a query loads a node with both labels, the ChildType model class will be used.
We've also talked about the ability to load modules to do multiple labels, though we weren't able to think of a good example, so I'd welcome one.

Create separate classes for insert and save

Is this a good idea? Instead of create a class with two method (insert and update) and two validation methods (validateInsert and validateUpdate), create three classes: one called ProductDB, another ProductInsert (with methods Insert and Validate) and another ProductUpdate (with same methods of ProductInsert).
Is this more readable, flexible and testable?
PaulG's answer leans more towards the traditional domain object pattern, which I'm not in favor of. Personally, my preference is to have a separate class for each process (like your ProductInsert and ProductUpdate). This is akin to what one sees in the simple bank example where Deposit is a instance of a class as opposed to a method on a BankAccount class. When you start thinking about business processes that have more stuff, like rules and actions to be taken and auditing/persistence of the action itself (say a ProductInsert table to track insertions), the more you realize the business process should be a first class citizen in its own right.
This sounds like a language-independent question. I would just create the one class and call it Product, and have the appropriate methods within the class. Think about what a mess it would be when actually instantiating your separate objects (unless you have static methods).
Also having a concrete Product class will allow you to store object specific information.
Ex:
Product myProduct = new Product()
myProduct.name = "cinnamon toast crunch"
myProduct.price = 3.99
In my opinion have separate classes would make your code a lot less readable and testable.

Paper form to database

I am doing a Rails 3 app that replaces a paper form for a company. The paper form spans two pages and contains a LOT of fields, checkboxes, drop downs, etc.
I am wondering how to model that in the DB - one approach is to just create a field in the DB for every field on the form (normalized of course). That will make it somewhat difficult to ad or remove fileds since a migration will be needed. An other approach is to do some kind of key/value store (no - MongoDB/CouchDB is not an option - MySQL is required). Doing key/value will be very flexible but will be a pain to query. And it will directly work against ActiveRecord?
Anyone have a great solution for this?
Regards,
Jacob
I would recommend that you model the most common attributes as separate database fields. Once you have setup as many fields as possible then fall back to using a key-value setup for your pseudo-random attributes. I'd recommend a simple approach of storing a Hash through the ActiveRecord method serialize. For example:
class TPS < ActiveRecord::Base
serialize :custom, Hash
end
#tps = TPS.create(:name => "Kevin", :ssn => "123-456-789", :custom => { :abc => 'ABC', :def => )'DEF' })
#tps.name # Kevin
#tps.ssn # 123-456-789
#tps.custom[:abc] # ABC
#tps.custom[:def] # DEF
If your form is fairly static, go ahead and make a model for it, that's a reasonable approach even if it seems rather rudimentary. It's not your fault the form is so complicated, you're just coming up with a solution that takes that into account. Migrations to make adjustments to this are really simple to implement and easy to understand.
Splitting it up into a key/value version would be better but would take a lot more engineering. If you expect that this form will be subject to frequent and radical revisions it may make more sense to build for the future in this regard. You can see an example of the sort of form-builder you might want to construct at something like WuFoo but of course building form builders is not to be taken lightly.