How do you set timestamps in version 4.0?


#1

The way we were setting timestamps is no longer working.

┆ ┆ repo.changeset(attrs).map(:add_timestamps)

The example here seems to be out of date: http://rom-rb.org/learn/repositories/changesets/

Because repo no longer has the changeset method. Are there any examples on how to do it in the new version?


#2

Changesets are now available directly on relations. See Core / Changeset docs.


#3

@solnic Apologies, this might just be a newbie mistake. But when I try to access the changeset method through the relations I still get the ‘undefined method `changeset’ error. Am I missing something?

 [6] pry(IndieNinja::API)> users_repo.users

=> #<IndieNinja::API::Persistence::Relations::Users name=ROM::Relation::Name(users) dataset=#<Sequel::Postgres::Dataset: "SELECT \"users\".\"id\", \"users\".\"email\", \"users\".\"first_name\", \"users\".\"last_name\", \"users\".\"created_at\", \"users\".\"updated_at\", \"users\".\"identity_provider_id\" FROM \"users\" ORDER BY \"users\".\"id\"">>

[7] pry(IndieNinja::API)> users_repo.users.changeset
NoMethodError: undefined method `changeset' for #<IndieNinja::API::Persistence::Relations::Users:0x007fb958a320a0>
from (pry):6:in `<module:API>'

#4

Do you have rom gem as a dependency and require it? It should require rom-changeset which adds Relation#changeset method.


#5

@solnic That was the issue!! I only had rom-repository and rom-sql in my Gemfile!

Thank you.


#6

For anyone coming across this here is a working example on how we got timestamps working:

We have a timestamps module which we include in our repos and it looks like this:

  module Persistence::Timestamps
  ┆ def create(attrs)
  ┆ ┆ super root.changeset(:create, attrs).map(:add_timestamps)
    end

  ┆ def update(attrs)
  ┆ ┆ super root.changeset(:update, attrs).map(:add_timestamps)
  ┆ end
  end

#7

I have also problem with setting timestamps. My repo looks like:

require_relative './repository_base'

class DocumentationRepository < ROM::Repository[:documentations]
  include RepositoryBase
  # ...
end

And repository base is:

module RepositoryBase
  def self.included(base)
    base.class_eval do
      struct_namespace Entities
      commands :create, update: :by_pk, delete: :by_pk
    end
  end

  def create(attrs)
    super root.changeset(:create, attrs).map(:add_timestamps)
  end

  def update(attrs)
    super root.changeset(:update, attrs).map(:add_timestamps)
  end
end

However create and update methods don’t seem to be reloaded. Still getting ROM::SQL::NotNullConstraintError for timestamps.

Edit - quoting @flash_gordon:
@buszu that’s because the commands macro overrides your create/update methods in the target class. If you’re using changesets just do

def create(attrs); root.changeset(:create, attrs).map(:add_timestamps).commit

and don’t use commands for update it’s similar,

def update(id:, **attrs); root.by_pk(id).changeset(:update, attrs).extend(:touch).commit


#8

Don’t you need to prepend RepositoryBase instead of including it so create/update would actually override base methods?