Overview

The Selector-Connector is a data model for organizing your FileMaker table occurrence graph. It is something we’ve been loosely collaborating on with our friend and colleague Todd Geist. I say loosely, because during the evolution of the model, we never really reviewed each others work, but talked in very general terms about our progress. The fact that we ended up with something so functionally similar makes me think that we’re actually onto something! Todd has a great post and video on his approach here.

We’re also using Selector-Connector as the data model for the new  SeedCode Complete and it is one of the primary reasons we feel Complete is working so well; seeing how Selector-Connector is letting folks extend and modify Complete also tells us this approach is being validated.

The most important thing to me about the Selector-Connector model is that the techniques themselves are not new new at all. It uses powerful, native techniques that have been around since FileMaker 7–like global keys and cross-joins–but it organizes them as a pattern that we can describe, much like we can describe the Anchor-Buoy pattern.

FileMaker Data Models: Extending Anchor-Buoy

The Selector-Connector should be seen as an extension of the currently predominant data model, Anchor-Buoy. Anchor-Buoy is arguably the most widely adopted FileMaker standard in the development community, and there are two very good reasons for that.

  1. It organizes the graph very clearly with a small set of rules
  2. It has a great name that is very visually descriptive.

We want to make sure we don’t lose either of those things  if we’re going to tinker with the model. In general terms, Selector-Connector keeps the current Anchor-Buoy model but builds “on top of it.” We’re just going to “bend” its rules a little bit.

A very basic interpretation of the Anchor-Buoy rules would be:

  1. All layouts must reference Anchor Table Occurrences
  2. Interacting with Buoys is only done from the context of their Anchor
  3. Anchor Table Occurrences cannot be related to each other.

By sticking to these rules, the Anchor-Buoy model forces us to be aware of context and it also limits the chance of us doing an operation out of context, like picking the wrong table occurrence for a portal; very important things in FileMaker and generally these benefits have outweighed the draw-backs of Anchor-Buoy, and that’s why it’s the standard.

The Pop-Over Cometh

As I mentioned above, there’s nothing technically new to the Selector-Connector model. So what changed to start us down this road? For me, it was the introduction of the Pop-Over in FileMaker 13. Here was a great new object that would be a light weight alternative to pop-up windows and dialogs.

It would be great for picking records from a portal, and for editing and creating records. And, using the new slide panels, selecting, creating, and editing, could be done all in one place! FileMaker Inc. seemed to have a similar thing in mind as the demo files that came with 13 had a nice example of this “all in one place” behavior: bring up a pop-over with a portal and filter for the record you’re looking for. If you can’t find it, then hit new and “slide” to a new record form right in the same pop-over…very slick! We were starting to work on the new SeedCode Complete and I saw a great design pattern taking shape.

However, when I started exploring this, I realized (obviously) that these pop-overs would have to be done as single purpose objects: even though both Projects and Invoices would need to pick Contacts, I wouldn’t be able to use the same pop-over as it would be bound to the context of the Project or Invoice layout. Even if I was using a virtual list for my Contact Picker, the portals would each still need their own buoys attached to Projects and Invoices. This suddenly seemed like madness, and I was determined to find a way to copy and paste my pop-overs from Anchor to Anchor and have them work with very little modification.

Universal Context

If we wanted the pop-overs to work universally, then there was no way around it, we would need to have a context for them to work in, and the idea of Universal Context was born. For a long time, Todd and I were both using this description of the model as the Selector itself hadn’t taken form. Here’s a representation of our first pass.

We decided to “compromise” on the Anchor-Buoy rule of Anchors being related to each other. We still don’t want them directly related to each other, or even interacting directly with each other. However, we do want them all to be able to access the Universal Context table occurrences of Home and Virtual List Rows. This way, any Anchor layout can all use the same portal on our Pop-Over Selector. Not only can they use the same portal, but the scripts that reference the portal can also be generic: and we’re a little closer to having the portable pop-over we’re after!

What about Record Locking?

The idea of the above graph is that I can set the RowsToShowGlob global field in Home and control the contents of my virtual list (setting a list of contacts to select from, for example). But what if another user is trying to do the same thing? This isn’t a Session Model, and we don’t want to have to manage multiple records in Home to prevent record locking, so how can we get around that? It turns out that if the Home table only has global fields in it, you’ve, in essence, made it a global table that multiple people can interact with without locking. This was really a critical milestone in the process. By having a central/single TO that we could connect through, we could enforce a similar, although slightly looser, model as Anchor-Buoy.

It’s important to note that we are interacting with the Home and the Virtual List Rows from the context one of the Anchors, and when doing this the central TO does not lock. However, if you create a layout in the context of the Home layout, and open a related record from there, then you do lock that central table preventing another user from doing the same. Working with the “universal context” tables from the Anchor causes the Anchor record to be opened, and not Home, which is the behavior we want. So, this is a rule from Anchor Buoy that needs to be maintained for this model to work: All user layouts should still be in the context of an “Anchor.”

Create From Anywhere

The model above solved my problem of being able to use a Contact Picker Pop-Over from any of my layouts, but I also wanted to be able to create new contacts right from my pop-over. Since we’ve already extended the Anchor-Buoy model for our Virtual List, we’ll extend it a little bit further and create a dedicated TO for contact creation. So now you’ll see a table occcurence called CreateContacts hanging off our Home table occurrence below.

We can create new Contacts through this relationship. If the relationship between Home and CreateContacts is a creation relationship and the ContactIdGlob in home is empty, we can create a new Contact simply by typing into a field in the CreateContacts table occurrence. The Contact id is an auto-generate field and this value for the new record will be pushed back into the global. This behavior may seem a little strange, but has existed for as long as I can remember in FileMaker and is referred to as the “pop-back” or “magic key.” For us it allows us to create a new Contact from anywhere by creating a temporary “parent” in Home, and we no longer need to go to a Contact layout to do this. We can use our Pop-Over Contact Picker on any layout to both pick and create contacts! Problem Solved and our graph is not a mess.

The Selector

Soon after we got this part working, we began to realize that there was more we could do with this model. If we’re using this Universal Context to create records from anywhere, then we can also very easily use this same model to view and edit records from anywhere. Master Detail or Selection Portals are very common in FileMaker, and we soon realized that the Universal Context would work great for them.

Typically an Anchor would need two Buoys to a related table to do a proper Master Detail view. Normally we’d click on a portal row of our first Buoy to get the id of the record we clicked. We would then set that id to a global to set up a relationship to the second Buoy where we would see additional data about the selected record. With Selector-Connector we can now set that global in our central Home Table Occurrence and use the relationship to CreateContact for our detail view. This means we can get rid of that second Buoy for the detail, and more importantly, any Anchor that wants to see Contact details can use that same Table Occurrence.

This is really the birth of the Selector. The central table is now no longer called Home, but the “Selector”. The table occurrences to its right are the “Selected”, and they’re also the relationships that let us create new records. We’ve now consolidated, pickers, creation and master-detail into a single “component” of the graph instead of a bunch of similar Buoys attached to each of your Anchors.

 The Connector

As we started working with this new model, there was this great sense of relief that we weren’t “fighting” with FileMaker like we have in the past. Context and Layouts were still tied to the Anchors, and it was living up to the promise of being the best of both worlds! In addition, we started to see some residual benefits.  For one, since most of the global keys were being moved to the Selector, we didn’t need them in actual data tables anymore. In SeedCode Complete, we were able to remove virtually all global fields from our the data tables. This keeps them much easier to work with, particularly if integrating with another data source or doing imports as you don’t need to wade through all the globals. This led to the idea of the Connector.

For me, the Connector is about modeling the graph to not just symbolize what’s a layout and what isn’t, but the different logical components of the graph. Initially we were thinking we had just two components, the Anchor-Buoy component and the Selector component, but once you adopt that model, it can be taken a little further. Really, the Selector is different than the Virtual List, so we decided to make our graph represent that. We also now have a place where we can keep indexed values available to all Anchors as well. Things like settings or graphics can also be cross-joined to our central Connector and accessed from anywhere. These things working together is the full Selector-Connector model.

In conclusion, I’d like to remind you of this great Picasso quote my mother recited to me for as long as I can remember, and how I think it applies here.

“Learn the rules like a pro, so you can break them like an artist.”

-Pablo Picasso

After going through this exercise, I believe that Anchor Buoy was not necessarily what the developers of the graph had in mind, but it was an absolutely critical step in our collective development. The idea of approaching something like the Selector-Connector without a complete and thorough understanding of FileMaker Context would be daunting and probably fruitless. The only reason we can use, or even talk about, a model like this is because of what Anchor-Buoy has taught us, and I want to re-emphasize the idea that the Selector-Connector (as I see it) is an extension and/or continuation of Anchor-Buoy. We’ve worked hard to learn and honor its rules, so we might be ready for a little artistry.

Need more? Checkout “Selector-Connector: the basics

Tagged with →  

31 Responses to FileMaker Data Modeling with Selector Connector

  1. Mark Scott says:

    Jason,

    Great article; thanks!

    Seeing some of the history and evolution behind your and Todd’s development of the model is most interesting. I’ve been spending some quality time refactoring a project over to the Selector-Connector model and am loving its simplicity. The big part, which I just started tackling, is moving the TOs involved in my scripted Find UI over to Connector rather than hanging off individual anchors. Those don’t have to move to S-C, of course; S-C is not all-or-nothing. But my entire Find UI gets a lot more robust and extensible — a lot more more modular — if I can pull it off.

    Looking forward to seeing how this continues to evolve.

    Mark

    • Jason Young says:

      Hi Mark,
      You are 100% right on that this is not all-or-nothing, and thanks for emphasizing that!
      It is nice that you can break a relationship from an Anchor to a Buoy and then reconnect the Buoy to the Selector, and not have references to the Buoy break for the Anchor in question…but you still have to redirect the other Anchor references, so there is a bit of a migration process.
      Thanks so much for posting and Cheers!
      -Jason

  2. Paul Jansen says:

    I have already been looking at this after watching Todd’s video and it look really very interesting. Am I right in thinking that if we use the selector to reduce duplication of TOs we will need to use script triggers on record change to keep everything in sync, thus exchanging one complexity for another. (I’m thinking of layouts based on Invoices, Orders, Jobs etc not each having a directly related contact TO in their TOG but using the selector to show the relevant related contact(s)

    • Marc Wood says:

      If I understand correctly, you wouldn’t use the selector TOs to display related data, only to select and create records to relate.

    • Jason Young says:

      Hi Paul,
      Thanks and great point.
      In general, I would say that relationships that are “persistent” should still use the traditional AB approach. For example, the InvoiceContact is a persistent part of the Invoice “entity” and is something that should not change, so for this we will use a Buoy. However, a “selected” contact, like we would do with a Master-Detail view is not persistent part of the Invoice “entity,” so moving it to the Selector would be appropriate.
      That’s pretty general, but that’s how I’ve been approaching it.
      Cheers,
      Jason

      • Paul Jansen says:

        I guess I was thinking of a more ‘extreme’ approach in order to get rid of multiple identical sub TOGS: Person – Address – Phone – email etc It really annoys me have this kind of duplication as it seems really inefficient. Seems like there is, as always, work to be done. I’d love to see a ‘real’ graph using AB and SC combined…

  3. Ben Graham says:

    Thanks so much Jason for sharing this development process. I had not yet watched Todd’s video, it has been a tab in awaiting for some time, now after reading it is time. :)

  4. Richard Dyce says:

    Jason – I think it’s great this finally is a codified, named pattern, and the layout ideas are great. One thing maybe worth mentioning – it makes using the standard custom functions for GetFieldName() / GFN() and GetTableName / GTN() easier when constructing SQL queries from anywhere. (because you need a link between TOs in order to pass in fields if you want to avoid hard-coding or using field ids.)

    • Jason Young says:

      Hi Richard,
      Right, good point. Todd has a theme that “lots of little things” become easier with this model, and I think this is a prime example.
      Cheers!
      -Jason

  5. Shawn A. Krueger says:

    Can we expect some sessions on this at DevCon this year?

    • seedcode says:

      I don’t think we can officially comment on this until the schedule is announced but I would not be surprised to see Jason talking about this at the conference. =)

  6. Andrew Hinshaw says:

    Nice work gentlemen and thank you for sharing!
    Is there evidence of this model impacting performance or is the primary benefit for cleaning up the graph?

    • Jason Young says:

      Hi Andrew,
      Right, great point!
      I haven’t gone too too deep with empirical numbers, but it’s basically a wash performance wise, testing into the millions.
      It’s a good point, and one I should emphasize: that this is not about performance, but organization/modularity. The fact that performance is a wash makes it a viable model. It’s not too surprising, to me, that performance is the same as the basic relationships are the same, just re-arranged a bit.
      If anything, this model might add a few extra TOs, but these are going to be skinny/global only TOs that seem to have a very light footprint and worth the organizational benefits.
      Cheers,
      Jason

  7. […] Update 2/24/15 –  Jason Young wrote a great blog post about using Selector Connector with Seedcode Complete. […]

  8. Daniel Wood says:

    Hi Jason and John, great article and a very interesting concept here. I’ve been looking into this a little bit to see whether there is anything we can use here for our own frameworks. We use an Anchor-Buoy structure with an Interface table acting as the Anchor, and as such we work on a session model so each user has their own Interface record.

    I was intrigued by your record locking comment when it came to globals, as we have tried to go down this route in the past without success. The majority of fields on our interface records are all global, yet we must still maintain individual records. I read your paragraph on this and did some more testing making sure every field was global, but I’m having no luck working around locking. While it is true that you can have two users set globals on the same interface record, the record itself will still become locked once a single user begins to edit a related record via that record (and given this is premise of the whole technique it kind of falls down at this point).

    Can you clarify your points on the record locking? I’ve tested this again and had no luck. My simple test involves 2 global fields on a single record, one of which is a key field relating through to a customer record. Two users on the same interface record, and one of those users is currently editing a record via relationship. THe other user is unable to modify any global field or related field as it is considered locked by way of the relationship (locking happens all the way up the chain from buoy to anchor based on what is being edited, global or otherwise).

    cheers!

    • Jason Young says:

      Hi Daniel.
      Thanks so much for chiming in!
      When you say “on a single record” that may be the sticking point, so I want to clarify. The Connector and Selector shouldn’t have any layouts attached, because opening the related records from a layout in this context will lock the Selector or Connector record, so all these operations need to be done from one of the “Anchors” to avoid locking the central “global” tables.
      You can create a single record “Interface” table layout for the central dashboard view and connect it just like the Anchors and that works great and is what we’re doing in Complete, and what Todd is doing as well.
      This is something Todd and I talked about a LOT, so I am a little embarrassed that I didn’t cover this here! I’m pretty sure Todd covers this here, but I’m hoping to get out a public demo file on this soon as well.

  9. AlanG says:

    Thanks for sharing this – as really great idea. I *think* I have my head around it, but just to double-check: why could the two tables ‘Connector’ and ‘Selector’ not be replaced by just the ‘Selector’ table? I understand that the two ideas can be used independently, but can all of the functionality of the universal ‘Connector’ table not be performed by the Cartesian relationship to the ‘Selector’ table?
    Thanks again for this.

    • Jason Young says:

      Hi Alan,
      I think this is a great point, and is probably more of a personal style issue than being critical to the model. Both Todd and I started with what you’re describing and it works great.
      My issue with it is that my “Selector” for Complete ended up being about 120 global fields, so breaking the relevant groups of globals into their own TOs was much easier to keep track of, and seemed more accessible for our customers to approach and modify.
      Todd talks about this in terms of modularity, and that TOs should represent operations as specifically and explicitly as possible, and I like that as well.
      However, like I said, I think going with a single Table/TO for this, and even the Virtual List Component, should be fine from a technical point of view, and maybe even an advantage in a smaller scale application with a finite number of TOs.
      Thanks and Cheers!
      -Jason

  10. seedcode says:

    GoZync was one of the other antecedents for Selector-Connector as we wanted our sync scripts to be able to consider (select) and modify any record without having to switch contexts (and accidentally commit records) to do it. So Selector-Connector in GoZync gave developers a really easy way to reason about what’s happening in a sync: on the left of the “Selector-Connector” TO (called “GoZync”) you have your hosted tables and on the right you have your mobile tables.

    It’s definitely proved it’s usefulness there as such a setup can accommodate all sorts of sync workflows.

  11. Tom D says:

    Hi,
    Thanks for sharing this!!
    I’m trying to implement this, wondering if maybe MVC becomes more achievable …
    Anyway, that aside, I’m trying to use a scriptstep “Go to Related” starting from the Selector. Probably another procedure would be better? Could you give me some insight on here?
    Thanks, Congrats on the great find!

    • Jason Young says:

      Hi Tom,
      Thank you for the post! I think Selector-Connector and MVC work great together. In Complete. The Selector-Connector allows us to run our main UI file as a single window solution, and having a controller file to do background finds for loading virtual lists, etc. works great!
      The Selector works great for navigating, and is exactly how we do it in Complete. What’s nice is you can put one record id in the selector and navigate to it, but you can also pass in a list of ids and when you do the GTRR, you’re in a found set of those records.
      For the GTRR, you don’t want to start the process from the Selector, in fact the Selector should have no layouts associated with it, as that can potentially cause the record to be locked and other users wouldn’t be able to use it. Instead you want to go “through” it and want to start from one of the “Anchors”.
      If you look at the last image in the Post, for example, you would start on a layout associated with Contacts, set an invoice ID in the Selector and then do a GTRR to SelectedInvoices and specify a layout associated with the Invoice “Anchor”.
      Let us know if that helps!
      Cheers!

  12. Hi, Jason. Thank you for this great article.
    I’ve translated it into Japanese and put it on my blog.
    You can find it at:
    http://notonlyfilemaker.com/2015/03/selector-connector/

  13. Alexander Zueiv says:

    Jason, what was the largest graph you implemented this technique on?

    I’ve tried similar techique many years ago, in 2008 I believe, on a large and very complicated 46-table system. There were over 40 Anchors joined together via the table Home. The final TOG consisted of 679 table occurrences.

    In those years computers were not so fast. Even opening that solution locally took several seconds, because of it’s TOG size. And working with the graph was a real pain. It took several seconds each time you opening the graph. Then, it took next several seconds to look at a “beach ball” when you first click on any TO. Then, if you change anything in the graph – even just move a TO – and click OK, FMP showed Rebuild dependences message for a while.

    So, I never used such a scheme since that time. But probably new FMP features allow to reduce the number of required TO’s even in that solution? Maybe it worth to try it again?

    I’ve just converted that old solution to FMP 14 and opened it locally on a new iMac. Well, the delays are not so long as they were in those days, but they yet present. And FMP yet shows Rebuild dependences message when I just move a TO. I’ve tried to delete the table Home to break the graph into separate TOG’s, then all delays gone. The problem is definitely in the TOG size. This scheme cannot work well for solutions with over 600 TO’s.

    The question is where is that range at which this schema still works?

  14. Hey Jason,
    Do you have any ideas about how to use selector-connector in a multiple window environment?

    • jason young says:

      Hi Wayne,
      Interestingly, one of my motivations for Selector-Connector was to be able to create a true single window solution. Both for simplification’s sake, but also to finally allow a true maximize in Windows.
      Of course, the problem with a multi-window environment is that the windows within a file share the same global fields, so would also share the same “selected” records and virtual list values. Depending on what these windows are doing, this may not be a problem, i.e. this window only selects these entities, otherwise you’ll get some global “collision”.
      One thing to consider is using multiple files for each window, that way the globals will be pegged to their file and no collision would be possible.
      hth,
      Jason

  15. Mike says:

    Every time I look at Selector-Connector, is just seems like an overcomplicated way of addressing an easily fixed shortcoming of Anchor-Buoy: allowing reusability of context-sensitive UI elements like a contact picker.

    But I solved this problem by violating the prime directive of A-B: linking the Anchors as their semantics dictate. IE, Contacts would be linked in a typical business solution to Invoices, and Addresses to Contacts. Just like in the old days pre-relationship-graph. That way, anywhere where the idea of an “Address” makes semantic sense (IE, in an Invoice context) you can just refer to it, and it works! Heresy, I know. But if every basetable that you might want to pick a Contact for is related to the Contacts table in the logical way that the semantics of your system dictate, then you can copy and paste your contact record picker popover into any context where it makes semantic sense to pick a contact, and it just works. You can paste a Contacts::ArbitraryField_t onto an Invoice Line Item layout, an Invoice layout, an Address layout, wherever, without worrying about it. I’m forever reusing portals and popovers in multiple contexts just by copying and pasting them from one to the other, no need for all the abstruse high concept complexity and buzzword compliancy. I don’t see what advantage Selector Connector offers over that to make the added complexity worth it.

    And the simpler way also allows you to look at the relationship graph and immediately see visually how all entities represented by the database are semantically related, rather than seeing them all connected together, even including entities that logically have nothing to do with each other, by identical vanilla cartesian joins.

    They say the mark of a creative child is the tendency to find more complex solutions to problems than is necessary. Is that what model is? If I’m missing something, I’m really curious to know what (without having to sit through a 40 minute video to find out the secret, sorry, I detest sitting through video content), because nothing I’ve seen relating to S-C, neither explanatory webpage nor demo file, conveys what problem it actually solves that the more straightforward solution of simply having your tables be related to each other in the manner their entity scheme logically suggests doesn’t, and yet, I keep on hearing about it again and again. So I’m really curious. Why all the hullaballoo?

    • Jason Young says:

      Hi Mike,
      Thanks! It’s a good point. I think the target audience for SC is the strict Anchor Buoy crowd. Outside of them, I think there has been something of a collective yawn to the idea. Ray Cologon described it to me as a “solution to problems introduced solely by anchor buoy,” and I think you’re making the same point.

      The reasons some devs go for AB is pretty well discussed, and SC is framed to appeal to them as a way of preserving what they like about AB without having to settle for some of the limitations. For me, personally, I like delivering products that are close to AB, as it makes them familiar to most developers, and is a good starting point if they want to vary from the model. I also know AB is popular in dev houses where you have multiple developers working on the same project. A strict model helps consistency, and AB graphs tend to be more wysiwyg then other models (although not always).

      That wysiwyg quality is what I like the most about SC, I can easily point to a part of the graph and say “this is what’s happening here, this is what’s happening there,” much like I can with AB, even if it’s the first time I’ve seen the solution.

      Cheers,
      -Jason

  16. BrianP says:

    I’m very new to Filemaker; I’ve stayed away because to the TO complexity. I just bought FMP advanced now the SQL is available. Isn’t it easier to just create the relationship you need in an SQL statement? I’ve done a lot of work in C# and VB stitching together SQL statements in code, or snippets stored in a database table.

    I haven’t had FMP 14 for even 24 hours yet. I ran across this discussion while reading a review of ‘the missing manual. I’m glad to be coming into such a helpful community.

  17. Hi everybody. Sorry if I am a bit dummy, but I cannot understand the second part about connector.
    For me it’s very clear selector, but why to do another Table as Connector if you can do it with selector ??
    Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

Share →
DOWNLOAD
DayBack Calendar
Download DayBack and we'll send you a couple short emails with tips on how to modify it and use some of the coolest features.
Thank you! Please download: DayBack Calendar
Need More?
SeedCode tips & example files in your inbox
Need More?
SeedCode tips & example files in your inbox
Want More?
Be the first to see articles and tips like these
DOWNLOAD
TimeZync
Download TimeZync and we'll send you a couple short emails with tips syncing your FileMaker Go files.
Thank you! Please download: TimeZync
Want More?
Be the first to see articles and tips like these