# Find when you have the model name but not the class

**URL:** <https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521>\
**Category:** Rails\
**Created:** [November 10, 2006, 5:54pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521 "2006-11-10T17:54:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 5:54pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/1 "2006-11-10T17:54:28Z")

</div>

Hi,

How can I get a model class and then search on it if I only have the  
model name?

I have created an item\_history to track the changes of an item in a  
stock list. I use this method in the Stock model, to create the history  
information:

```auto
def add_history(item, process)
    history = ItemHistory.new
    history.model = item.class.to_s
    history.item_id = item.id
    history.status = item.stock_status.name
    history.comments = item.comments
    history.process_name = process
    if user = User.find(session[:user_id])
      history.who = user.user_name
    end
    history.save
  end
```

I am then able to list the history of a particular item, or all history.  
In the list of all history, I use:

```auto
<% if Stock.find(:first, :conditions => ["id = ?", 
history.item_id.to_i]) -%>
            <td><%= link_to "#{history.model}/#{history.item_id}",
                    :controller => history.model.pluralize.downcase,
                    :action => "show",
                    :id => history.item_id -%></td>
          <% else -%>
            <td><%=h history.model -%>/<%=h history.item_id -%></td>
          <% end -%>
```

This either outputs model/id or the same with a link to that item if the  
item exists (if the action being recorded is delete, the item won’t be  
there).

How do I recreate the “if Stock.find” statement to accept any model  
name. I want something the will let me grab an instance of the model  
class by passing history.model to it, and then let me do a find on that  
class.

Is that possible?

I want to reuse this system in another model.

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 6:19pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/2 "2006-11-10T18:19:54Z")

</div>

Try:

eval(model\_name).find(:all)

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 6:01pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/3 "2006-11-10T18:01:53Z")

</div>

You can do history.item.class.find …  
Which will do a Stock.find if item is an instance of class Stock,  
Badger.find if item is an instance of Badger etc…

Fred

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 6:24pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/4 "2006-11-10T18:24:56Z")

</div>

2 ways I know of…

Object.const\_get(“MyClass”)

eval(“MyClass”)

not sure which is more efficient

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 6:51pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/5 "2006-11-10T18:51:08Z")

</div>

David F. wrote:

> Try:
> 
> eval(model\_name).find(:all)

Splendid. This worked a treat:

if eval(history.model).find(:first, :conditions =\> [“id = ?”,  
history.item\_id.to\_i])

Thank you David and Chris for your prompt and useful responses.

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 6:59pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/6 "2006-11-10T18:59:18Z")

</div>

Frederick C. wrote:

> You can do history.item.class.find …  
> Which will do a Stock.find if item is an instance of class Stock,  
> Badger.find if item is an instance of Badger etc…
> 
> Fred

Thanks Fred. I missed that when I responded earlier.

I don’t think that will work because I am only storing the model name in  
history\_item, and not an instance of the model class. The class of the  
history object is always HistoryItem I think.

Rob

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 7:00pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/7 "2006-11-10T19:00:26Z")

</div>

Rob N. wrote:

> > always HistoryItem I think.

In fact ItemHistory

---

<div class="post-metadata">

**Author:** ![reggieb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/3e96dc/32.png) [@reggieb](https://www.ruby-forum.com/u/reggieb)\
**Post date:** [November 10, 2006, 7:11pm UTC](https://www.ruby-forum.com/t/find-when-you-have-the-model-name-but-not-the-class/75521/8 "2006-11-10T19:11:05Z")

</div>

Rob N. wrote:

> history.item\_id.to\_i])
> 
> Thank you David and Chris for your prompt and useful responses.

You can also do model\_name.constantize.find…  
if however ‘model\_name’ isn’t the actual name of the class - meaning  
‘MyTable’ and not eg. ‘my\_tables’ - you need to call classify first, eg.  
model\_name.classify.constantize.find…

eval is also pretty cool though :]

Hope this helps!  
Cheery-o  
Gustav P.  
removed\_email\_address@domain.invalid
