Trouble using FetchLinks with another other than key_text in Rails

I keep running into an issue with FetchLinks with related content. I’m only able to pull in key_text fields even though your docs say that I should be able to pull in Title, for instance.

I’m able to pull in key_text fields in my controller from a related content type with this code similar to this (which I have working for key text fields on related content). This the show action for my blog post controller:

uid = params[:uid]
@post = api.getByUID("blog", uid,
  { "fetchLinks" => "contributor.name, contributor.bio",
    "ref" => ref
  }
)

But any time I try to use another type of field, such as Title, I get this error:
undefined method for nil:NilClass

I’m simply trying to create a “Related Article” connection between two content types which I’ve modeled—“Blog post” and a “Report”. I’d like to display the title of a Report and link to it on a blog post when the editor creates a content connection to a Report on a blog post.

I was trying to use FetchLinks similar to my example above with “contributor.name” but I keep getting a NoMethodError.

I’m using Rails with the Prismic Starter App.

Also, to make this a little more complicated, how would you do this if you were trying to use the blog post / report association through a slice?

On the Blog Post, I’d like for them to add a content relationship to a Report in the slice zone so that they can control the order of where the Report Title / Link appears on the blog post.

Hi @leemc. I need to look into this to see if it’s a mistake in the documentation or not. I’ll let you know what I find.

Okay so I’ve taken a look and it appears that the documentation is incorrect. I’m sorry for the confusion and I’ve updated that article so that nobody else is confused by this in the future.

Unfortunately the fetchLinks option doesn’t work with Rich Text or Title fields at the moment. As a workaround you can either change the Title field to a Key Text field (which you’ve seen works just fine), or you can run a second query for all the linked documents which would give you all their fields to use as you need.

As for your second question, I’m not really sure what you mean. Can you clarify? Perhaps with an image or sketch so that I can better understand what you’re trying to do?

Thanks. Glad to know the documentation was incorrect and I’m not insane!

1. Re: First Question. I would prefer be able to keep all of my posts modeled the way they are now with “Title”. Is something like this what you recommend?

uid = params[:uid]
@post = api.getByUID("blog", uid,
  { "fetchLinks" => "contributor.name, contributor.bio",
    "ref" => ref
  }
)

report_id = @post["blog.related_content"].id
@report = api.getByID(report_id) if !report_id.nil?

2. Re: Second Question.

I can get this working with some ugly code in my view like this:

<% when "related_article" %>
  <% related_post_id = slice.non_repeat["post"].id %>
  <% related_post = api.getByID(related_post_id) if ! related_post_id.nil? %>
  <%= related_post["post.title"].as_text %>
<% end %>

Is there a better way to pull in the related content if that related content is in the slice zone?

@leemc Yes, the first query looks good, but what I would actually do in your case is to gather all of the linked documents and query them all at the same time.

So get the report_id same as you show but also parse your Slice Zone to get any related posts. Then you can put all their ids into an array and query them all at the same time as shown here:
https://prismic.io/docs/ruby/query-the-api/query-documents-by-id-or-uid#5_0-query-multiple-documents-by-ids

Then instead of querying the related post in your view, you can just use the document you already queried to display the title.

Thanks @levi.

I guess where I’m stuck is on how to “parse your Slice Zone”. How do you do this in a Rails controller?

@leemc Sorry, I’m not a Ruby/Rails developer, so I don’t know exactly how it would look. All you would need to do is to reduce the array of slices to the ones with links to related posts, then map that so you end up with an array of document IDs of the related posts.

@levi

Ok, I’ve discovered something odd about this problem. If I loop through my slices in the view like this it works as expected:

  <% @post["blog.body"].slices.each do |slice| %>
    <% case slice.slice_type when "text" %>
      <% if slice.non_repeat["rich_text"] %>
          <%= slice.non_repeat["rich_text"].as_html(link_resolver).html_safe %>
      <% end %>

    <% when "data_visualization" %>
      <% if slice.non_repeat["related_data"] %>
          <% data_viz_id = slice.non_repeat["related_data"].id %>
          <% data_viz = api.getByID(data_viz_id) if !data_viz_id.nil? %>
          <%= data_viz["data_viz.embed"].as_text.html_safe %>
      <% end %>
# etc. continues through each slice_type
    <% end %>

But for that blog post show action I’m using api.getByUID

Whereas, on single pages when I query the page with something like this @page = api.getSingle("overview"), then that same code as above in the view works when the page is published, but not when it is previewed.

The weird thing is that the blog post works in preview mode. The only difference in the two are getSingle vs. getByUID.

Is this a bug or the intended behavior of the Prismic API. Is there another way to query single pages that will work?

@leemc This sounds very strange. I’m not sure what the issue is here without taking a closer look. Can you share your project files with us so that we can investigate further?

You can either send a zip file of your project or a link to the code on Github. If you don’t want to make this public, then you can send this to me in a private message.

@levi I can’t make it public, but would be happy to send it to you in private. I just sent you a message.

@leemc

I’ve taken a look at the project files but can’t figure out what might be wrong. So I’ll need to pass this over to our dev team to investigate. Hopefully someone there will be able to sort this issue out. They will let you know when they pick this up from their queue.

Appreciate it @levi. I’m working around it by adding a UID to each page and then querying that instead, but would prefer not to do that because there is no need for editors to have to edit the url for a page like “/contact” or “/about”