質問

I have a named scope set up in my rails application that is used to locate a record either by its ID (directly from the index view) or a UUID (from an email - basically only so that users can't enter in any ID and view a record)

scope :by_uuid, lambda { |id| where('id = ? OR uuid = ?', id, id) }

This is used in the show action, so the ID comes from the url, like

services/114

services/74c083c0-8c29-012f-1c87-005056b42f8a

This works great, until you get a UUID such as 74c083c0-8c29-012f-1c87-005056b42f8a This, rails unfortunately converts to the int value and we get services/74 AS WELL AS the record with the correct UUID

Adding a .first to the scope will not help because the order could be different for each record, so that does not work.

Is there a way to prevent rails from converting the ID like this and taking the string literally? Obviously, there will not be a record with an ID that matches that, but if it goes willy-nilly with the integer values of the string passed to it, we could get anything back.

Using the dynamic finders, such as

Service.find_by_uuid

or

Service.find_by_id

work as intended, however we need to be able to retrieve a record using the UUID OR the ID in the same method (show).

Is there a way to do something like

Service.find_by_id_or_uuid
役に立ちましたか?

解決

We fixed this issue with the following change to the scope:

scope :by_uuid, lambda { |id| where('binary id = ? OR uuid = ?', id, id) }

This ensures that the id string is taken by its binary value instead of being converted into an int. However, this will ONLY WORK WITH MYSQL BASED APPS

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top