Nick DiZazzo
Nick DiZazzo

Reputation: 73

How do I create a Rails 3 model backed by a database table without having its attributes dynamically generated by ActiveRecord?

I'm attempting to create an API for a third party service and I've been given access to a replicated database with all of the data I need. Unfortunately, there is a limitation on what privileges have been granted to use in MySQL as to not expose proprietary database design.

The database is set up to expose certain database tables as views, and SELECT privileges are granted on those views.

I have some model backed by a table that doesn't adhere to typical Rails table-naming conventions, defined as follows:

class MyAPIModule::City < ActiveRecord::Base
    set_table_name "VIEW_CITY"
end

Any query where ActiveModel tries to dynamically build attributes for the model fails, example:

MyAPIModule::City.find(1)

Failure:

Mysql2::Error: SHOW VIEW command denied to user 'theuser'@'thehost' for table 'VIEW_CITY': SHOW CREATE TABLE `VIEW_CITY`
ActiveRecord::StatementInvalid: Mysql2::Error: SHOW VIEW command denied to user 'theuser'@'thehost' for table 'VIEW_CITY': SHOW CREATE TABLE `VIEW_CITY`

The problem is that the priveleges don't allow ActiveRecord to run the "SHOW CREATE TABLE" query to gather column information and build the model attributes.

Is there a way to hard-code the table schema that would prevent ActiveRecord from needing to query the database for the table construction with "SHOW CREATE TABLE"?

EDIT:

In conjunction with my reply to sameera207:

class MyAPIModule::City
    include ActiveModel::Validations
    include ActiveModel::Conversion
    include ActiveModel::SerializerSupport
    extend  ActiveModel::Naming

    ...
end

Upvotes: 4

Views: 507

Answers (3)

Nick DiZazzo
Nick DiZazzo

Reputation: 73

I'm going to answer my own question because I found a very nice solution that allows you to do everything I was trying to accomplish, and provides similar query methods that ActiveRecord does...

DataMapper is a gem that supports explicit database-field mapping, intended for use with legacy databases, or databases where Rails doesn't have control over the schema.

Upvotes: 0

hermiti
hermiti

Reputation: 496

You could try defining the select scope manually:

default_scope select("column1, column2, column3")

Upvotes: 0

sameera207
sameera207

Reputation: 16629

I'm not sure is there a way to skip the column constriction from the data base, however one work around would be directly execute your sql command.

It will require some coding manually,

class MyAPIModule::City < ActiveRecord::Base
    set_table_name "VIEW_CITY"

    def find(id)
       obj = ActiveRecord::Base.connection().execute("select * from your table")
       #above will return an array, so you will have to create your object
       obj
    end 

end

Upvotes: 1

Related Questions