Working with Relationships in Rails

45 views
Skip to first unread message

CLG

unread,
Apr 22, 2013, 2:26:58 AM4/22/13
to neo...@googlegroups.com
Intense beginner question here but I've been unable to find the answer anywhere.

I have model, show.rb:

class Show < Neo4j::Rails::Model
    property :show_name, type: String, index: :exact
    has_n :booked_bands
end

I have another model, band.rb

class Band < Neo4j::Rails::Model
    property :band_name, type: String, index: :exact
    has_n :playing_shows
end

I create a show.

show = Show.new
show.show_name = "Test Show"
show.save

I create a band.

band = Band.new
band.band_name = "MyBand"
band.save

I create a relationship by which the band is playing the show:

band.playing_shows << show
band.save

The crux of my question: how do I access the band object's properties when I retrieve it from the show?

Whenever I try to do something like this:

theshow = band.playing_shows

I get a response like this:

=> #<Neo4j::Rails::Relationships::NodesDSL:0x39fe9ce1 @dir=:outgoing, @storage=#<Neo4j::Rails::Relationships::Storage:0xcb5efc8 @rel_class=Neo4j::Rails::Relationship, @target_class=Neo4j::Rails::Model, @incoming_rels=[], @node=#<Band:0x3adcbf25 @errors=#<ActiveModel::Errors:0x57f9cc39 @base=#<Band:0x3adcbf25 ...>, @messages={}>, @_relationships={:playing_shows=>#<Neo4j::Rails::Relationships::Storage:0xcb5efc8 ...>}, @_properties={"band_name"=>"MyBand", "_classname"=>"Band"}, @changed_attributes={}, @_create_or_updating=nil, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x3fd3659b>, @previously_changed={}, @_properties_before_type_cast={:band_name=>"MyBand"}, @validation_context=nil>, @rel_type=:playing_shows, @persisted_related_nodes={:outgoing=>[#<Show:0x50d8dc5a @_relationships={}, @_properties={}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x258e4566>, @_properties_before_type_cast={}>]}, @outgoing_rels=[], @persisted_relationships={}, @persisted_node_to_relationships={:outgoing=>{#<Show:0x50d8dc5a @_relationships={}, @_properties={}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x258e4566>, @_properties_before_type_cast={}>=>#<Java::OrgNeo4jKernelImplCore::RelationshipProxy:0x349319f9>}}>>

If I do this:

theshow = band.playing_shows.to_a

I get this, which looks more manageable:

=> [#<Show:0x50d8dc5a @_relationships={}, @_properties={"show_name"=>"Test Show"}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x258e4566>, @_properties_before_type_cast={}>]

This looks like it is referring to my test show as expected.

but then when try "theshow.show_name" I receive "NoMethodError: undefined method `show_name' for #<Array:0x14eebce6>"

If I try to loop through it like this:

theshow.each do |s|
  s.show_name
end

I get this:

=> [#<Show:0x50d8dc5a @_relationships={}, @_properties={"show_name"=>"Test Show"}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x258e4566>, @_properties_before_type_cast={}>]

How do I get JUST "Test Show" to output? I can't find any sample apps that really show me and I'm too green to make full sense of the documentation. It seems so simple, I'm sure I am doing something wrong.

Any clarification is appreciated.

Andreas Ronge

unread,
Apr 22, 2013, 3:38:13 AM4/22/13
to neo...@googlegroups.com
Hi

Since you have declared a has_n relationship you will get a Ruby Enumerable (which the Neo4j::Rails::Relationship has mixed in) of Node objects when you use the
playing_shows accessor method.

So, if you want to look at the first show node object you simply use the .first method (just as you would like on an array) on the enumerable.

  theshow = band.playing_shows.first

Notice you can also declare a has_one relationship.

See Gist:

Cheers


--
You received this message because you are subscribed to the Google Groups "neo4jrb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4jrb+u...@googlegroups.com.
To post to this group, send email to neo...@googlegroups.com.
Visit this group at http://groups.google.com/group/neo4jrb?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

CLG

unread,
Apr 23, 2013, 12:00:17 AM4/23/13
to neo...@googlegroups.com
Excellent! Thank you. Got it, I was over-thinking... or maybe under-thinking. ;-)

My model now looks like this:

class Show < Neo4j::Rails::Model
  property :show_name,        type: String, index: :exact
  has_n(:bands).from(Band, :playing_show)
end

class Band < Neo4j::Rails::Model
  property :band_name,        type: String, index: :exact
  has_n(:playing_show).to(Show)
end

When I go to an individual Show node's page and try to view all Bands appearing:

<% @show.bands.each do |b| %>
  <%= b.band_name %><br />
<% end %>

It returns:

Band1
Band2
[#<Band:0x2be040e5 @_properties_before_type_cast={}, @_relationships={}, @_properties={"band_name"=>"Band1"}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x199c36ee>>, #<Band:0x418b04a5 @_properties_before_type_cast={}, @_relationships={}, @_properties={"band_name"=>"Band2"}, @_java_node=#<Java::OrgNeo4jKernelImplCore::NodeProxy:0x6a20cc11>>]


The problem, of course, being the block after the band names. When I go in the opposite direction, using "@band.playing_shows.each" while trying to see all Shows that a band is playing (instead of all bands playing a show) it does not append the additional relationship data.

Andreas Ronge

unread,
Apr 23, 2013, 2:39:11 AM4/23/13
to neo...@googlegroups.com
Hi

Sorry, I don't understand the problem. The block after the band names is strange, maybe you have set the band_name to the string "[#<Band: ..." ?
What do you man with not appending additional relationship data ?
Can you try with a clean database ?

Cheers




--

CLG

unread,
Apr 24, 2013, 1:53:52 AM4/24/13
to neo...@googlegroups.com
That was my very awkward way of saying "What's the deal with all the '[#<Band: ...' stuff?" Answer was that it was a new-to-Rails thing. I was using <%= in a view, should have been <%. Amateur hour.

<% @show.bands_playing.each do |b| %>
  <%= b.band_name %><br />
<% end %>

Here is a Gist of the entire thing with examples of accessing the relationship from each direction in case someone else wants more examples. https://gist.github.com/subvertallchris/30c334854be70f1a9ea0

Thanks for the help!

Chris
Reply all
Reply to author
Forward
0 new messages