Link to other nodes


(Epipheus) #1

First off, I love this CMS, btw. It’s the first one that resonated with me, but I have to be missing something. Is there a simple way to add a field to a node that represents a link to another node? Some builtin? Or is it something like:

field :button_link, :select, choices: -> {PushType::Node.all.map(&:title)}, multiple: false
or
field :button_link, :select, choices: -> {PushType::Node.where(type: "blah").map(&:title)}, multiple: false

I would expect something like:

field :button_link, :node_links # or even something sexier


(Aaron Russell) #2

There’s a field for that :slight_smile:

The RelationField is the way to go here. With relations, the field name must end in _id (or _ids if using the :multiple option).

A few examples:

# By default the relation class will be inferred from the field name
# So here we assume you're associating with an Article
field :article_id, :relation
field :article_ids, :relation, multiple: true

# Alternatively, explicitly set the relation with to :to option
field :feature_article_id, :relation, to: :article

# The :scope option allows you to invoke scopes on the relation class
field :article_id, :relation, scope: -> { published }

# If you pass a hash tree then the select field options will be a nested list
field :page_id, :relation, to: 'push_type/node', scope: -> { published.hash_tree }

# By default the select field will map the object id to the value, and title as the option text
# This can be customised with the :mapping option
field :comment_id, :relation, mapping: { value: :id, text: :author_name }

# In your templates, access the associated object the way you'd expect
@node.article # => #<Article>

In the future I’d like to see a Node Browser field, which allows you to browse through and select a node from your entire content tree… but until then, the relation field is the way to go.


(Epipheus) #3

cool… and the nested list is however nested the hash is? very cool.


(Epipheus) #4

wait, is .hash_tree a builtin for getting a hash of a Node’s descendents?


(Aaron Russell) #5

Yes. We depend on closure_tree for the tree-like behaviour, so we get all of the class and instance methods closure tree provides:

I’d be a bit careful with .hash_tree - in the example I gave above it’s essentially querying the entire tree which on a big site might not be a sensible thing to do.


(Priit Pärna) #6

Instead of starting a new thread… I’ll post my question here.

I would like to create a relation field what’s connected/mapped to two nodes (page, event_page)

# Something like that, note that this code DOESN'T work!
field :link_to_page_id, :relation, to: [:page, :event_page], scope: -> { published }

Is there any way to make this happen? Currently using bad published.hash_tree scope what includes all nodes

field :link_to_page_id, :relation, to: 'push_type/node', scope: -> { published.hash_tree }

Thanks! :nerd_face:


(Aaron Russell) #7

Yes I think you could do this, by adding the node types as part of the scoped query:

field :link_to_page_id, :relation, to: 'push_type/node',
  scope: -> { where(type: %w(Page EventPage)).published }

(Priit Pärna) #8

Thanks! I just added .hash_tree to the end so it’s visually better to understand some structure.

field :link_to_page_id, :relation, to: 'push_type/node', scope: -> { where(type: %w(Page EventPage)).published.hash_tree }