I thought this is an easy one, but: I have created a record, and later
would like to retrieve it again.
Here is an excerpt of my schema:
create_table “dicts”, force: true do |t|
t.string “dictname”
…
end
My model ensures that dictname is unique:
validates :dictname,
presence: true,
length: { minimum: 3 },
format: { with: /\A\D/ },
uniqueness: true
In my controller, I tried this to fetch a Dict object, when the value
for the :dictname field is stored in variable dict_name:
if Dict.exists?(:dictname => dict_name)
logger.debug('found dictionary with name '+dict_name)
dictid=Dict.where(:dictname => dict_name).select(‘id’).first.id
logger.debug(‘dictid=’+dictid.inspect)
@dict=Dict.find(dictid)
However, the line to calculate dictid fails with
TypeError (can’t cast Hash to integer)
which would suggest that the hash argument to the ‘where’ method is
unexpected. But this can’t really be, can it?
So, my questions:
On May 26, 2014, at 8:38 AM, Ronald F. wrote:
My model ensures that dictname is unique:
if Dict.exists?(:dictname => dict_name)
unexpected. But this can’t really be, can it?
So, my questions:
ActiveRecord already has a finder that can do all this in one line:
Dict.first_or_create(url: params[:dictname])
Assuming that’s the only thing needed to create or find an existing
Dict, you should be all good there.
Walter
Sorry, meant dictname:, not url: that’s my app that has URLs, not yours.
Walter
Walter D. wrote in post #1147113:
ActiveRecord already has a finder that can do all this in one line:
Assuming that’s the only thing needed to create or find an existing
Dict, you should be all good there.
No, it should not create one. If there is no suitable record, I want to
display an error message to the user. Hence, find_or_create isn’t
suitable for me.
BTW, I also tried
Dict.find(:dictname => dict_name)
but this too complained that there is a hash, which can’t be converted
to an integer.
Ronald
On May 26, 2014, at 9:03 AM, Ronald F. wrote:
Dict.find(:dictname => dict_name)
but this too complained that there is a hash, which can’t be converted
to an integer.
Dict.find_by_dictname() will do that for you. If you add the bang to it,
you will get a full-on error, if you don’t you will get nil and no error
is raised. If you are using the error to trigger your 404, then you want
the bang version.
Walter
Thanks, I will try this!
I wonder: Where do I find a specification for this feature? I guess
Rails automatically generates this kind of find_by_… functions for
each attribute in my model, which as “uniqueness” set. Where is this
documented? My biggest problem with rails is getting from the API docs
the information I need.
Just for my understanding: Could you also please explain, why my
original (complicated) version failed?
Ronald
This could be written as this:
@dict = Dict.where(:dictname => dict_name).first
It will either return a record, or nil.
Walter
Walter D. wrote in post #1147134:
@dict = Dict.where(:dictname => dict_name).first
It will either return a record, or nil.
Thanks a lot. This works perfectly well!
Ronald