Module: Basecamp::Services::TodolistsExtensions

Defined in:
lib/basecamp/services/todolists_extensions.rb

Overview

Merge-safe update and read-modify-write edit for todolists (and todolist groups), prepended onto the generated TodolistsService (see the on_load hook in basecamp.rb).

BC3's TodolistsController#update rebuilds the recordable from only the permitted params, so PUT /todolists/{id} is a full replace: a body that omits description ERASES it. The sparse PUT — the natural thing to write — is therefore destructive on the raw endpoint, which stays available as #replace.

Both compose the public get and replace methods, so hooks observe the two wire operations (+get+ then replace), not a synthetic composite.

Neither is atomic: there is no conditional-update signal on this endpoint, so a concurrent write between the GET and PUT is overwritten — last write wins for the whole representation. The window is one round-trip. Use replace to overwrite deliberately.

Defined Under Namespace

Classes: TodolistFields

Instance Method Summary collapse

Instance Method Details

#edit(id:) {|fields| ... } ⇒ Hash

Applies a read-modify-write block to a todolist: GETs the current todolist, yields its full writable state (TodolistFields), and PUTs the whole thing back. Clearing a field means setting it empty ("") — an untouched field keeps its current value. If the block raises, the edit aborts and nothing is written.

Not atomic — see the module docs for the GET→PUT race.

Examples:

.todolists.edit(id: 123) do |list|
  list.name = "🚨 #{list.name}"
  list.description = "" # clearing = setting empty on a full object
end

Parameters:

  • id (Integer)

    todolist id

Yield Parameters:

  • fields (TodolistFields)

    the todolist's writable state, to mutate in place

Returns:

  • (Hash)

    the updated todolist

Raises:

  • (ArgumentError)

    if no block is given

  • (Basecamp::UsageError)

    if the block leaves the name empty



70
71
72
73
74
75
76
# File 'lib/basecamp/services/todolists_extensions.rb', line 70

def edit(id:)
  raise ArgumentError, "edit requires a block" unless block_given?

  fields = fields_from_todolist(get(id: id))
  yield fields
  put_fields(id, fields)
end

#update(id:, name: nil, description: nil) ⇒ Hash

Sets the given fields on a todolist and preserves everything else: GETs the current todolist, overlays the explicitly-passed keyword arguments, and PUTs the full representation back. An omitted (+nil+) field is untouched, guaranteed; an explicitly-passed "" clears.

Not atomic — see the module docs for the GET→PUT race. Use #replace to overwrite deliberately, or #edit to clear fields.

Parameters:

  • id (Integer)

    todolist id

  • name (String, nil) (defaults to: nil)

    new name (nil = keep current)

  • description (String, nil) (defaults to: nil)

    new description (nil = keep current, "" clears)

Returns:

  • (Hash)

    the updated todolist

Raises:



44
45
46
47
48
49
# File 'lib/basecamp/services/todolists_extensions.rb', line 44

def update(id:, name: nil, description: nil)
  fields = fields_from_todolist(get(id: id))
  fields.name = name unless name.nil?
  fields.description = description unless description.nil?
  put_fields(id, fields)
end