Closed cheerfulstoic closed 10 years ago
Chris, how about you and me old dinosaurs use the rels. Method, we support both way, need to think more and see more examples On 24 Jul 2014 21:19, "Chris Grigg" notifications@github.com wrote:
Err... I sent that from my phone and then edited without realizing that you want to still use has_(many|one) but change the meaning. I'm not so sure about that... but I won't object if you guys outvote me. I can adapt, I just like the directness of defining direction with two master methods. Feels like less of a learning curve, too.
— Reply to this email directly or view it on GitHub https://github.com/andreasronge/neo4j/issues/380#issuecomment-50064937.
Since Brian agreed to back off for now, let's leave it alone and let this die! Haha. But Brian, if you find that you have a lot of success with belongs_to/etc,... maybe it'll be worth revisiting? Or just doing it in a separate gem, neo4j-belongs_to or something?
Just got this working in the conversion branch of my app, works great. This is the most nitpicky suggestion I think I've ever had, but do you guys think that :outgoing
/:incoming
might work as better keywords than :outbound
/:inbound
? I'm sorry, I'm sorry, I want this closed as much as you, it was just something I noticed while typing it up. :-/
Overall, though, I'm really happy with it. It's immediately clear what is happening at all times with each association. When origin
is added in, it'll be even better; when ActiveRel (or whatever its final name is), it'll be really great.
Can you add in support for the before/after callbacks I added a week or two ago? I think @sahin is using them and since he was the first to bring up renaming relationship types, it would be a shame to leave that behind.
Also, Brian, awesome work getting this (and all earlier variations) in there!!!
Thanks (and thanks for all the feedback ;)
I was just going to implement origin, but I have a question:
class Show
has_many :outgoing, :bands
end
class Band
has_many :incoming, :shows, origin: :bands
end
What if that :incoming
were :outgoing
instead? Should :origin
just mean that we create an appropriate relationship type prefixed with #
or should we bother verifying how it links up to the other relationship?
For now I'm just going to have it make the relationship (and maybe validate that you can't have both type
and origin
at the same time)
So you mean, what if they're both set to :outgoing
? I think it should only be concerned with the relationship type, unless it's simple enough to add that check that you feel like doing it. They'll post an issue and we'll politely tell them to read the docs more carefully. ;-) (We'll probably point this out a dozen times in the docs since it's such an important guideline.)
But I think it should just verify that the corresponding method exists and that it has a type specified or magically created. If it can't find the association, it fails; if they both have :origin
set, they both fail. Seem reasonable?
I had a look at the specs query_spec.rb
in your branch and it looks very good.
I also prefer outgoing
and incoming
. A detail, I guess your specs will run slowly since you create the node space in an before(:each) block instead of before(:all)
If we're checking that the method exists on the other side it's probably pretty simple to check that they're not both going in the same direction. I'll add that to avoid the questions ;)
I think I actually prefer inbound
and outbound
, but it's not a big preference. What about in
, out
, and both
?
And yeah, the spec will run slower because of that. Honestly there's probably room to be using before(:all) in some cases. I'm also thinking that I'm going to be splitting up the spec shortly because it's becoming hard to remember what all is setup. Will probably split out the association chanining stuff and then the has_(one|many) stuff will probably need to be organized and tested on a feature-by-feature basis.
Unless Andreas feels reeeaally strongly about it, I propose we leave inbound/outbound alone for now and we can discuss it when we're not sending messages back and forth. It would be a 5 minute conversation or half a dozen comments to this issue over a 12 hour period! Haha.
:) Sorry just an another comment Regarding testing I think we should write more unit test and mock more since it will give much faster tests. I like to mix many small unit tests with a few end to end tests. I would also like to clean up my own specs.
Regarding inbound and outbound (sorry): I would prefer in, out, and both. If you change I would like to change in the neo4j-core as well.
Good to hear since I'm in the process of doing exactly that (regarding unit testing).
And yay, somebody agrees with me (regarding in/out/both)! ;) @subvertallchris Objections?
No objects! Full support! This is awesome! Go team!
Great discussion ! Feels like we come up with a really awesome new API. Looking forward seeing the PR.
FYI I just pushed some changes to support in/out/both and origin. I've also refactored the specs to be easier to read and made unit specs for the Association class. I just found out that a lot of other specs are failing, but I've got to go to bed now, so I'll look at that in the morning. Next up after that is implementing the association callbacks ( @subvertallchris I know you're waiting on this to be working, so I'm happy for a hand on either point).
Just pushed some changes and it's getting closer. Have one question for @andreasronge though. I've been trying to convert the integration specs, but the doubles are multiplying. It comes down to the fact that the relationship creation/querying isn't using neo4j-core API methods like #rels
, #nodes
, and #create_rel
but rather using the core Query API. Does this seem like a good path to you? Do integration tests make as much since in this context? I'm somewhat experienced with mocks/stubs/etc... but I don't know that I'm comfortable knowing when they're appropriate.
I think it is important that the specs are simple and easy to understand. If there are too many stubs and mocks then I think either the code is too complex or the RSpecs tests are too coarse grained. I would also like to reorganize the existing rspecs (some of them are from the 2.x version)
Btw, I think we later on should measure the performance difference of using #rels and #nodes instead of the query api when using the embedded neo4j
It is just an amazing progress.
Can someone summarize the latest syntax?
is it? has_many :outgoing, :bands
and in the neo4j db, what will be name of the relation Show#outgoing#bands or just bands
It's all described at https://github.com/andreasronge/neo4j/wiki/Neo4j-v3-Declared-Relationships but here are some basics.
Automatically named relationships are prefixed with #, use the rel_type option with a string to set the type. There's also an :origin
option for reciprocal relationships or you can use ActiveRel to separate relationship logic.
#look for class Band, rel type is '#bands'
has_many :out, :bands
#look for class Band, rel_type is 'has_bands'
has_many :out, :bands, rel_type: 'has_bands'
#look for class Band, association is :people_playing_instruments, rel_type is 'has_bands'
has_many :out, :people_playing_instruments, model_class: Band, rel_type: 'has_bands'
#look for any class
has_many :out, :things, model_class: false, rel_type: 'has_things'
Thx, They look good. There was 100s comments. I totally skip the wiki. :) We will move to this branch and do some testing.
I am sure you all discuss it, I think it might be a very simple syntax for activemodel, mongoid users to make has_many ":outgoing," as default. to -> has_many :bands
if they want more control "in" or declare out then devs can write simply has_many :outgoing, :bands
EDIT: There, fixed my example. It's :out
, :in
, :both
, not :outgoing
, :incoming
. Had my wires crossed cause of your question. :-)
We actually did talk about having outbound as the default direction but I think we settled on requiring a direction first to keep things clear, explicit, and help the user be more aware of the fact that direction is a crucial part of an association.
This is in master now, no need to switch to a different branch. It was included with alpha 9.
cool. thx...
A dummy question.
I am trying to create the relations with new style. I couldnt make it work.
class NeoPerson
include Neo4j::ActiveNode
set_mapped_label_name('Person')
property :mongo_id; validates :mongo_id, uniqueness: true, presence: true
property :name, presence: true
has_many :in, :followed_by, model_class: NeoUser, type: 'followed_by'
end
class NeoUser
include Neo4j::ActiveNode
set_mapped_label_name('User')
property :mongo_id
validates :mongo_id, uniqueness: true, presence: true
index :mongo_id
property :name, presence: true
property :facebook_id
validates :facebook_id, uniqueness: true
index :facebook_id
has_many :out, :follow_person, model_class: NeoPerson, type: 'follow_person'
end
The code I was running is :
user = NeoUser.first person = Person.first.neo user.follow_person << person user.save! user.follow_person.to_a
in db, I cannot see the relation or in to_a, it is []
Your type doesn't match on the two models, is that deliberate? That wouldn't account for your issue, just pointing it out.
I wonder if using set_mapped_label_name
is causing any problems, I don't know how that affects things. What happens if you do it with person = NeoPerson.first
?
NeoPerson.first and NeoUser.first, they both working and I am getting
<NeoPerson mongo_id: "52f9500d776f72e1697a0000", name: "Alexander Payne">
let me check with out without set_mapped_label_name
bad news, it works perfectly without set_mapped_label_name.
so set_mapped_label_name is creating the problems.
user.follow_person.to_a
[#<NeoPerson mongo_id: "52f9500d776f72e1697a0000", name: "Alexander Payne">]
I fixed the type still same, so it is causing because of set_mapped_label_name
Yeah, it's the mapped label names for sure. When the association, it is making a cypher statement based on the class name, not its label name. It might be a quick fix, give me just a minute.
I can fix the relationship creation but querying for associations is a lot more complicated, @cheerfulstoic built it so he might know an easy fix.
cool, let me check
Don't get too excited, I haven't pushed anything yet. ;-)
:)
@sahin, let's move this over to #420.
Check out the query_experiment branch. For good examples see the query_spec:
https://github.com/andreasronge/neo4j/blob/query_experiment/spec/e2e/query_spec.rb
The code is a bit hairy right now, but I'm really excited about this approach. It takes over some of the conceptual ground of QuickQuery without the .qq method, it introduces a more ActiveRecordy has_many association, and it allows for calling class methods on QueryProxy objects (which are also now returned from has_many associations)
This is aping a lot of ActiveRecord, but I think it's taking it a step beyond what ActiveRecord is capable of doing. I'm really excited about it ;)
Some things that would need to be done: