ohm icon indicating copy to clipboard operation
ohm copied to clipboard

Getting last id

Open carina-akaia opened this issue 6 years ago • 6 comments

Is there a method for last id getting? Something like User.last_id, more low-cost (and low-level) than current User.all.ids[-1]

carina-akaia avatar Jun 03 '18 18:06 carina-akaia

The last ID is stored as a separate Redis key at <ModelName>:id.

You could get the last ID with a Redis GET:

Ohm.redis.call("GET", "User:id")

pote avatar Jun 03 '18 21:06 pote

Thanks for answer, it helps in my case. It seems like undocumented feature. I think it might be nice if that functional be realized as OHM model method instead of redis call.

carina-akaia avatar Jun 03 '18 22:06 carina-akaia

Can you add feature request label?

carina-akaia avatar Jun 03 '18 22:06 carina-akaia

@katecanaveral I just added the label. Not sure if I prefer Model.id or Model.last_id. Or maybe we just need to document how to get that value from Redis. What was your use case? You can leave your comments here, I guess the next version can include an improvement on this area.

soveran avatar Jun 04 '18 07:06 soveran

My case is using last user id for next id prediction, i use it in next username.

last_id = Ohm.redis.call('GET', 'User:id').to_i
    User.create(
        name: "user_#{last_id + 1}",
        ...
    )

User.all.ids[-1].to_i is bit laggy, sometimes i was getting username 'user_30', although last user id was >40 0_o

About method Model.last_id (i guess .id is implicit name), it's very usable and graceful alias for Ohm.redis.call('GET', 'User:id').to_i

carina-akaia avatar Jun 04 '18 12:06 carina-akaia

@katecanaveral regardless of the last id feature, I'd want to comment on a possible source of bugs with your approach.

If timed just right, you might get an incorrect name attribute in your users, since another user might be created between you calling GET User:id and creating the new user, which is a difficult bug to reproduce that is sure to cause you some pain if/when it happens.

But also: it doesn't seem like you need to store the name in an Ohm attribute for that model since the information you want is composed of the model id and a static string, a method like the one below might be enough:

class User < Ohm::Model
  def name
    "user_#{ id }"
  end
end

Maybe there are extra considerations that make you actually need a name Ohm attribute, but I'd still suggest an alternative implementation (like setting the name after the model is created, either synchronously or with a background job) to avoid a possible id/name mismatch bug, happy to help if you need any guidance.

pote avatar Jun 25 '18 20:06 pote