Class: Dato::MigrateSlugs::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/dato/migrate_slugs/runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, skip_id_prefix) ⇒ Runner

Returns a new instance of Runner.



10
11
12
13
# File 'lib/dato/migrate_slugs/runner.rb', line 10

def initialize(client, skip_id_prefix)
  @client = client
  @skip_id_prefix = skip_id_prefix
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



8
9
10
# File 'lib/dato/migrate_slugs/runner.rb', line 8

def client
  @client
end

#skip_id_prefixObject (readonly)

Returns the value of attribute skip_id_prefix.



8
9
10
# File 'lib/dato/migrate_slugs/runner.rb', line 8

def skip_id_prefix
  @skip_id_prefix
end

Instance Method Details

#add_slug_field(field) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/dato/migrate_slugs/runner.rb', line 109

def add_slug_field(field)
  validators = {
    unique: {}
  }

  validators[:required] = {} if field['validators']['required']

  slug_field = client.fields.create(
    field['item_type'],
    field_type: 'slug',
    appeareance: { title_field_id: field['id'] },
    validators: validators,
    position: 99,
    api_key: 'slug',
    label: 'Slug',
    hint: '',
    localized: field['localized']
  )

  client.fields.update(
    slug_field['id'],
    position: field['position'] + 1
  )
end

#item_typesObject



150
151
152
# File 'lib/dato/migrate_slugs/runner.rb', line 150

def item_types
  @item_types ||= client.item_types.all
end

#items_for(item_type_id) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dato/migrate_slugs/runner.rb', line 84

def items_for(item_type_id)
  items_per_page = 500
  base_response = client.request(
    :get,
    '/items',
    'page[limit]' => 500,
    'filter[type]' => item_type_id
  )

  extra_pages = (
    base_response[:meta][:total_count] / items_per_page.to_f
  ).ceil - 1

  extra_pages.times do |page|
    base_response[:data] += client.request(
      :get,
      '/items',
      'page[offset]' => items_per_page * (page + 1),
      'page[limit]' => items_per_page
    )[:data]
  end

  JsonApiDeserializer.new.deserialize(base_response)
end

#runObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/dato/migrate_slugs/runner.rb', line 15

def run
  print 'Fetching site informations... '
  title_fields
  puts "\e[32m✓\e[0m"

  title_fields.each do |title_field|
    item_type = item_types.find do |i|
      i['id'] == title_field['item_type']
    end

    print "Adding slug field to Item type `#{item_type['name']}`... "
    add_slug_field(title_field)
    puts "\e[32m✓\e[0m"

    items = items_for(title_field['item_type'])
    print "Generating slugs for #{items.count} items"

    items.each do |item|
      update_item(title_field, item)
      print '.'
    end
    puts "\e[32m✓\e[0m"

    puts
  end
end

#simple_slugify(item, title, suffix) ⇒ Object



42
43
44
45
46
47
# File 'lib/dato/migrate_slugs/runner.rb', line 42

def simple_slugify(item, title, suffix)
  return nil unless title

  slug = title.parameterize[0..50].gsub(/(^\-|\-$)/, '')
  skip_id_prefix ? "#{slug}#{suffix}" : "#{item['id']}-#{slug}#{suffix}"
end

#slugify(item, title, suffix) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/dato/migrate_slugs/runner.rb', line 49

def slugify(item, title, suffix)
  if title.is_a?(Hash)
    Hash[
      title.map do |locale, value|
        [locale, simple_slugify(item, value, suffix)]
      end
    ]
  else
    simple_slugify(item, title, suffix)
  end
end

#title_fieldsObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/dato/migrate_slugs/runner.rb', line 134

def title_fields
  @title_fields ||= item_types.map do |item_type|
    fields = client.fields.all(item_type['id'])

    any_slug_present = fields.any? do |f|
      f['field_type'] == 'slug' || f['api_key'] == 'slug'
    end

    next if any_slug_present
    fields.find do |field|
      field['field_type'] == 'string' &&
        field['appeareance']['type'] == 'title'
    end
  end.compact
end

#update_item(title_field, item) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/dato/migrate_slugs/runner.rb', line 61

def update_item(title_field, item)
  title = item[title_field['api_key']]
  counter = 0

  loop do
    begin
      slug = slugify(item, title, counter.zero? ? '' : "-#{counter}")
      return client.items.update(item['id'], item.merge(slug: slug))
    rescue ApiError => e
      error = e.body['data'][0]

      if error['id'] == 'INVALID_FIELD' &&
         error['attributes']['details']['field'] == 'slug' &&
         error['attributes']['details']['code'] == 'VALIDATION_UNIQUE'

        counter += 1
      else
        raise e
      end
    end
  end
end