STORYBLOK, RUBY: undefined method `[]' for nil:NilClass (NoMethodError) - ruby-on-rails

I don't know that much about RUBY, just thought that you guys might help me with this. I'm using Storyblok as my headless CMS and JEKYLL when I'm building serve it this is the error that I got;
33: from C:/project/test/_plugins/storyblok_generator.rb:8:in `generate'
32: from C:/project/test/_plugins/storyblok_cms/generator.rb:12:in `generate!'
C:/project/test/vendor/cache/ruby/2.7.0/gems/storyblok-3.0.1/lib/storyblok/client.rb:354:in `block (2 levels) in find_and_fill_links': undefined method `[]' for nil:NilClass (NoMethodError)
the code below is from _plugins/storyblok_cms/generator.rb
def generate!
timestamp = Time.now.to_i
links = client.links(cv: timestamp)['data']['links']
stories = client.stories(per_page: 100, page: 1, cv: timestamp)['data']['stories'] #line 12
stories.each do |story|
# create all pages except global (header,footer,etc.)
content_type = story['content']['component']
if content_type != 'shared'
site.pages << create_page(site, story, links)
end
rescue UnknownContentTypeError => e
# for production, raise unknown content type error;
# for preview and other environments, issue an warning only since the content_type might be available
# but the code handling that content type might be in a different branch.
Jekyll.env == 'production' ? raise : Jekyll.logger.warn(e.message)
end
site.data['stories'] = stories
site.data['articles'] = stories.select { |story| story['full_slug'].start_with?('articles') }
site.data['shared'] = stories.select { |story| story['full_slug'].start_with?('shared') }
end
the code below is from _plugins/storyblok_generator.rb
require "storyblok"
module Jekyll
class StoryblokGenerator < Jekyll::Generator
safe true
def generate(site)
StoryblokCms::Generator.new(site).generate! #line 8
end
end
end
Additional Info:
ruby version: ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x64-mingw32]
jekyll version: jekyll 4.2.1
OS: Windows 10

I've actually found the solution to this, So this error occurs because I have created a page template in Block Library in Storyblok and then firing bundle exec jekyll serve command in terminal without creating the page template source/file in my project directory.
So I have an about_us block (content-type) in Block Library created and then when I fire bundle exec jekyll serve without creating an about_us.html first in _layouts folder, It would trigger the error.
Solution;
Make sure to create the source/file first in the _layouts folder if you have created a block (content-type) in block library.

Related

Sudden "uninitialized constant PurIssue" error on STI_preload while upgrading rails to 7.0.1

I am in the process of upgrading a ~2 year old Rails app from 6.1 to 7.0.1
I have an STI setup where Pursuit is the main class and it has several other types as descendants:
# app/models/pursuit.rb
require 'sti_preload'
class Pursuit < ApplicationRecord
# ...
end
Descendant classes all look like this:
# app/models/pur_issue.rb
class PurIssue < Pursuit
# ...
end
--
# app/models/pur_goal.rb
class PurGoal < Pursuit
# ...
end
--
# app/models/pur_tracker.rb
class PurTracker < Pursuit
# ...
end
I have been using STI preload snippet as recommended by the Ruby Guides, and all worked well under Rails 6.0 and 6.1.
But now that I am upgrading to Rails 7.0.1, I suddenly get an "Uninitialized Constant" error for only the PurIssue subclass whereas all the other subclasses load fine:
Showing /Users/me/gits/rffvp/app/views/pursuits/_stats.html.slim where line #1 raised:
uninitialized constant PurIssue
Extracted source (around line #33):
33 types_in_db.each do |type|
34 logger.debug("Preloading STI type #{type}")
35 type.constantize
36 end
37 logger.debug("Types in database #{types_in_db}")
Trace of template inclusion: #<ActionView::Template app/views/layouts/_footer.html.slim locals=[]>, #<ActionView::Template app/views/layouts/application.html.slim locals=[]>
Rails.root: /Users/me/gits/rffvp
Application Trace | Framework Trace | Full Trace
lib/sti_preload.rb:33:in `block in preload_sti'
lib/sti_preload.rb:31:in `each'
lib/sti_preload.rb:31:in `preload_sti'
lib/sti_preload.rb:13:in `descendants'
app/models/pursuit.rb:71:in `<class:Pursuit>'
app/models/pursuit.rb:54:in `<main>'
app/models/pur_issue.rb:52:in `<main>'
app/views/pursuits/_stats.html.slim:1
app/views/layouts/_footer.html.slim:14
app/views/layouts/application.html.slim:13
I can't seem to figure out why PurIssue will not load anymore whereas all the other subclasses will. This is breaking my entire app since PurIssues are the most important data points.
Can someone point me to a Rails configuration change between 6.0, 6.1 and 7.0 that might cause this different behavior?
# lib/sti_preload.rb
module StiPreload
unless Rails.application.config.eager_load
extend ActiveSupport::Concern
included do
cattr_accessor :preloaded, instance_accessor: false
end
class_methods do
def descendants
preload_sti unless preloaded
super
end
# Constantizes all types present in the database. There might be more on
# disk, but that does not matter in practice as far as the STI API is
# concerned.
#
# Assumes store_full_sti_class is true, the default.
def preload_sti
types_in_db = \
base_class
.unscoped
.select(inheritance_column)
.distinct
.pluck(inheritance_column)
.compact
types_in_db.each do |type|
logger.debug("Preloading STI type #{type}")
type.constantize
end
logger.debug("Types in database #{types_in_db}")
self.preloaded = true
end
end
end
end
Zeitwerk shows the same error by the way:
$ rails zeitwerk:check
Hold on, I am eager loading the application.
rails aborted!
NameError: uninitialized constant PurIssue
/Users/me/gits/rffvp/lib/sti_preload.rb:33:in `block in preload_sti'
/Users/me/gits/rffvp/lib/sti_preload.rb:31:in `each'
/Users/me/gits/rffvp/lib/sti_preload.rb:31:in `preload_sti'
/Users/me/gits/rffvp/lib/sti_preload.rb:13:in `descendants'
/Users/me/gits/rffvp/app/models/concerns/validateable.rb:10:in `block in <module:Validateable>'
/Users/me/gits/rffvp/app/models/pursuit.rb:68:in `include'
/Users/me/gits/rffvp/app/models/pursuit.rb:68:in `<class:Pursuit>'
/Users/me/gits/rffvp/app/models/pursuit.rb:54:in `<main>'
/Users/me/gits/rffvp/app/models/pur_issue.rb:1:in `<main>'
Tasks: TOP => zeitwerk:check
(See full trace by running task with --trace)
I saw the same thing trying to do an upgrade to rails 7. I believe it originates with this change: https://github.com/rails/rails/commit/ffae3bd8d69f9ed1ae185e960d7a38ec17118a4d
Effectively the change to invoke Class.descendants directly in the internal association callback methods exposes a more longstanding implicit issue with invoking Class.descendants at all during the autoload, as the StiPreload implementation may result in a problem where it circularly attempts to constantize the original class being autoloaded. I've added an issue in the Rails repo here https://github.com/rails/rails/issues/44252

Ruby: parametrize string without Ruby on rails framework (Jekyll plugin)

I have plugin that takes attribute from post's front matter and uses it in permalink. Problem is I need to clean up any accents and diacritics from the string before putting it in to the permalink. Ruby on rails has method called parametrize which does exactly what I need but I have no idea how to use it in plugin.
This is plugins code I have:
module JekyllCustomPermalink
class CustomPermalink < Jekyll::Generator
safe true
priority :low
def generate(site)
# nothing to do, wait for hook
end
Jekyll::Hooks.register :documents, :pre_render do |doc|
begin
# check if jekyll can resolve the url template
doc.url
rescue NoMethodError => error
begin
if !doc.collection.metadata.fetch("custom_permalink_placeholders").is_a?(Array)
raise CustomPermalinkSetupError, "The custom placeholders need to be an array! Check the settings of your '#{doc.collection.label}' collection."
end
def doc.url_template
#custom_url_template ||= collection.metadata.fetch("custom_permalink_placeholders").inject(collection.url_template){|o,m| o.sub ":" + m, data[m].to_s.parameterize}
end
rescue KeyError
# "custom_permalink_placeholders"
raise CustomPermalinkSetupError, "No custom placeholders defined for the '#{doc.collection.label}' collection. Define an array of placeholders under the key 'custom_permalink_placeholders'. \nCaused by: " + error.to_s
end
end
end
end
end
but I get this error:
john#arch-thinkpad ~/P/blog (master)> bundle exec jekyll serve --trace
Configuration file: /home/john/Projects/lyricall/_config.yml
Source: /home/john/Projects/lyricall
Destination: /home/john/Projects/lyricall/_site
Incremental build: disabled. Enable with --incremental
Generating...
Jekyll Feed: Generating feed for posts
Liquid Exception: undefined method `parameterize' for "Žďořšťáčik":String in feed.xml
bundler: failed to load command: jekyll (/home/john/.gem/ruby/3.0.0/bin/jekyll)
/usr/lib/ruby/gems/3.0.0/gems/jekyll_custom_permalink-0.0.1/lib/jekyll_custom_permalink/custom_permalink.rb:20:in `block in url_template': undefined method `parameterize' for "Žďořšťáčik":String (NoMethodError)
What am I doing wrong ? How can I use this method which should be part of a string class but apparently it is not ? How can I achieve same result without ruby on rails framework ?
INFO:
jekyll 4.1.1
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
Thank you for help
Rails additions to base Ruby classes, like String#parameterize, are part of the Active Support Core Extensions. The activesupport gem can be installed and used independent of Rails.
To keep the default footprint low, ActiveSupport allows you to require only the individual extensions you want to use. In your case, you will need to require the string inflection extensions:
require 'active_support/core_ext/string/inflections'
"Kurt Gödel".parameterize
=> "kurt-godel"

Gettting undefined method `empty?' for nil:NilClass in my test suite when I try to call a Rails path helper (*_path) using Rails, Rspec

Rails 6.1.3.1
Rspec
basic behavior spec code:
describe "index" do
it "should show me the list" do
visit dashboard_targets_path
end
end
the routes file
namespace :dashboard do
resources :targets
end
error shows me the exception, but strangely it appears as if it isn't calling through to the app, just fails right in my test code:
1) interaction for Dashboard::TargetsController index should show me the list
Failure/Error: visit dashboard_targets_path
NoMethodError:
undefined method `empty?' for nil:NilClass
# ./spec/system/dashboard/targets_behavior_spec.rb:16:in `block (3 levels) in <top (required)>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/webmock-3.12.2/lib/webmock/rspec.rb:37:in `block (2 levels) in <main>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:46:in `block (2 levels) in <main>'
it seems to be failing inside the test code, if I drop into the debugger there and run dashboard_targets_path directly I also get the same exception, so the problem is just using the helper within the TEST ENVIRONMENT
within the dev environment, this function works
the problem here was the the config/environments/test.rb file does have default_url_options.
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
when you hit errors that disappear into the Rails gems, a good way to debug them is like so:
begin
// your failing code here
rescue StandardError => e
puts e.backtrace
byebug
puts e.inspect
raise (e)
end
WARNING: do not leave this code in your app or check it in unless you explicitly want to use exception handling for flow control (not recommended!). This is recommended ONLY for debugging purposes.
here you will see the full backtrace to the line number in the Gem where it is failing. when debugging Gems be careful— remember to un-do any changes you make and know that your monkey-patching inside of the Gem code doesn't affect your production code.

rpsec-rails with apartment Gem and Grape cannot set host with subdomain

I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.
But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.
#buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n
The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.
I tried this one:
https://github.com/influitive/apartment/wiki/Testing-Your-Application
But not works. I don't know why.
I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec
and tried to set the host by:
host! "g_m.lvh.me:3000"
#request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'
Nothing works!
I created a test case like the following grape link says:
https://github.com/dblock/grape/commit/99bf4b44c511541c0e10f4506bf34ae9abcccd75
require 'rails_helper'
RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }
#before(:each) do
#begin
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#rescue
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')
#end
#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"
#end
#end
#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end
#end
describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []
end
end
end
My configurations:
in spec/rails_helper.rb
config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/
All time this request sent by rspec-rails with
url: '/content/api/v1/questions'
host: 'www.example.com'
My test result shows:
$ rspec spec/requests/
F
Failures:
1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200
expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
abhi#ubuntu-trusty-64:~/my-app$
If anyone knows about the error and what I am doing wrong here, please reply/answer.
The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.
Add the following:
# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.
I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.

How to set up rack-offline in rails 3.2 app

How to make rake-offline work in rails 3.2.11 ?
I added initializer
offline = Rack::Offline.configure do
#cache "images/masthead.png"
public_path = Rails.public_path
Dir[public_path.join("javascripts/*.js")].each do |file|
cache file.relative_path_from(public_path)
end
network "/"
end
I added in routes
match "/application.manifest" => Rails::Offline
Rack::Offline.configure do
cache "assets/application.js"
cache "assets/application.css"
network "/"
end
and added manifest in html tag.
It throws error
/initializers/offline.rb:5:in `block in <top (required)>': undefined method `join' for "/Sites/Ruby/project/public":String (NoMethodError)
In Rails 3.2.11, Rails.public_path returns a String, not a Pathname object. (It looks like Rails master has it returning a Pathname object which is why rack-offline's documentation might say to use it that way).
Try this instead:
public_path = Pathname.new(Rails.public_path)
See https://github.com/wycats/rack-offline/issues/7

Resources