Content management system for media
First a light review:

You've got a bug, I think. Your map_type_to_class sets a feed_type_id variable, but your case statement is looking at a stream_type_id variable that I don't see anywhere.

Second, don't use so many return statements. It's Ruby; returns are implicit. So this you don't need returns in if...else or case branches you have in your question. In idomatic Ruby, you only see return if someone specifically wants to exit a method early (and even that's rare with well-factored code).

Lastly, this bit is redundant

tweet_urls = self.where(:feed_id =&gt; feed_id.to_i)
if tweet_urls.empty?
  return []
else
  return tweet_urls
end


Which, to all intents and purposes is the same as simply:

self.where(:feed_id =&gt; feed_id.to_i)


It's implicitly returned, and it's array-like, so there's no need to do anything special. It's either empty or it's not. If you want something that's truly an Array instance (and not just duck-typed), you can append a .to_a.

Anyway, what you're looking for is the constantize method for strings. What you've got is a fairly simple has_many relationship, you just want something like a string item_type column on your Feed model that contains the class name (as a string) instead of your current numeric ID.

From there it's a matter of implementing a polymorphic has_many (Rails already has a polymorphic option for belongs_to but that's a to-one association).

You could simply do

def Feed
  def items
    klass = item_type.constantize
    klass.where(feed_id: id)
  end
end


(yes that could just be one line).

You won't have all the fancy collection methods, caching, and other nice stuff Rails provides for regular associations, but you can add that if you want or simply make do without it (I recommend the latter unless you find it to be bigger hassle).

So in your FeedsController (or wherever), you're looking at something like

def show
  feed = Feed.find(params[:id])
  render json: feed.items
end


That should work as a super-minimal implementation. The point is really just that you store the class name, which you can then turn from a string into a class name constant with constantize.



Alternatively, you could use Rails' built-in associations, but there's more setup involved and it's not as clean to look at. Again, you'll want an item_type string column.

def Feed
  has_many :webpages # the class name Webpage is implicit
  has_many :pictures
  has_many :twitters # yuck, not a good name, but it'll imply the Twitter class

  def items
    association = item_type.underscore.pluralize # convert a class name to an association name
    send(associtation) # call the association method (e.g. `webpages`)
  end
end


The main advantage is that the items method is just a shortcut that provides the correct association object, so you have all the usual convenience methods. So you can do something like this for a webpage-type feed

Feed.find(some_id).items.create(params[:url])


Of course, the major issue is that it's not clear what's going on. Is items a collection of Picture? Of Webpage? If you just blindly try to create a Picture record from params meant for a webpage, things get messy.

So I'd stick to the first version, where items isn't an opaque alias for an association, and instead work a bit harder when adding new records and such.