Database views and Rails

17 12 2007

When it comes to using database views then most of us think that it is difficult to use them with Rails or we may not be able to use ActiveRecord with it. Since I experimented with it in the past so I thought why not share it with you folks.

There are several situations when we would like to use database views with our Rails application like:

Situation 1:

If we have a complex SQL query that we don’t want to code in your Rails app due to performance related or any other issues.

Situation 2:

When our database guys have already spent a great amount of time writing useful views that can be used in the current app

Situation 3:

When we have some repeated query to run in every select statement to fetch data from every table. For instance
Select * from table_name where created_on < today;

In that case we would prefer to have a view with this query and call that view.

In all the above situations, it is pretty easy to use our database views with Rails.

How?

Simply create your model as you would for a table and it will work fine just like your model for a database table.

Interesting thing is, apart from viewing data using views I can even update, delete and insert data in my database tables using my views with all those ActiveRecord/ORM niceties (in Sybase) as long as each database view consists of only one table. If you are using more than one table in your database views then you can only view data but cannot do delete, update and insert operation.

I think this is really useful if we have a database that do not conform to Rails conventions but we would like to follow those conventions without changing the current database if other applications depend on it as well. Simply create views for each table in the database and use those views for our models instead of actual tables.

Those single table views (in other words updatable views) will allow us to follow Rails database conventions without changing our existing database tables while also keeping our database guys happy ;o)

(Though we also have other options if we are not following rails conventions)

NOTE: I have tried updatable views only with Sybase and would love to know about your experience with other databases.


Sign up and be a part of SPhred.com and don’t forget to invite your friends ;o)


Actions

Information

18 responses

21 12 2007
Jose

Hi Nasir,

thanks for sharing this. I am actually thinking about using views for a different reason: Different users in my app can see different sections of data, even in just the one table. So I thought that creating different views of that table will act a security mechanism for me, hiding the data that I can’t show to certain users.

Regarding the updatable views, although I haven’t tested it yet, I remember from my DB lectures in college that a view can be updated as long as you have all the primary keys of all the tables involved in the view in the view itself. This would also apply to all the “mandatory” fields in the tables involved.

cheers,
José

21 12 2007
nasir

Hi Jose,

Absolutely right, that’s one of the main reasons behind using database views and thanks for pointing it out.

9 01 2008
tony petruzzi

my friend, you are a God. I’ve been looking at how to use views and stored procedures in Rails for quite sometime and you’re right, there is no documentation out there.

My point in using views is to mash together databases. Using linked servers in SQL Server you can call two different database in a view and combine the results with a union all.

Thanks once again.

17 02 2008
Jordan Brough

No luck for me on SQLLite –

>> OtherPerson.find(:first).save
ActiveRecord::StatementInvalid: SQLite3::SQLException: cannot modify other_people because it is a view

Looking around it appears that it may be possible with a trigger on the view, but that’s too much maintenance for my current needs.

17 02 2008
Jordan Brough

Oops, misspelled SQLite as SQLLite

18 02 2008
nasir

Never tried it with SQLite so can’t comment on that ….. :(

5 03 2008
Jean-Marc

Hi Nasir,

been doing the same thing on MySQL 5.0 and so far I’ve had no problem either. And yes, views are updatable too on MySQL.

cheers!

Jean-Marc

29 07 2008
abhi

Hi Nasir,

I am having problems accessing existing database views. These views are based on tables being modified by a different application. eg of a view name is ‘__CC___LONDON_STAFF’ .

I know that these views don’t adhere to the normal rails convention but these wern’t created by me. i can map the models to similar named tables using the set_table_name method, but this doesn’t seem to work with the views.

any suggestions would be a great help. I am using Ms-sql server 2000 as the database, and am using rail 2..

many thanks,
abhi

29 07 2008
nasir

Abhi

I think the first step would be to create a simple view yourself and check whether it is working or not?

For instance, for table Article or article create a view with a different name called articles and corresponding model Article.

See what happens then?

29 07 2008
abhi

Hi Nasir,

I tried creating two different test views using sql enterprise manager. I based one of the views on a single table and the other one on two related tables.. I tried creating a scaffold for each view at a time and then tried migrating to the current version.
it kept failing saying that a table with that name already exisits. For some reason it was creating a new table with an id and timestamp info.
i had a look at the schema.rb

29 07 2008
abhi

I had a look at the schema.rb file.

it is listing all the tables but not listing any of the views?
i am not sure it is accessing any of the views from the database.

29 07 2008
nasir

I am not sure why do you need to run the migration for view if your table is already in the database and you are only referring to the view.

Can I suggest that once your view and model is ready then simply fire up the console and check whether you can do CRUD operations on your view/model?

If that works then that means it is fine.

I would also advise to remove any migration file created when you create a model based on the view rather than the table because there is no point in running migration for views or there is?

29 07 2008
abhi

hi got it working thanks
Me trying to migrate to the current version was causing the problem. I removed the migration file that was created and it seems to work like a charm. Thanks for your help.. much appreciated.

abhi

30 07 2008
abhi

hi Nasir,

I am back with a small problem. The view I was trying at access has a field called Job-Title’. Notice that its a hyphen and not an underscore here.
In the index.html.erb file I can manage to display all the other fields using the for loop apart from this one.
Think ruby associates hyphen as minus operator. When I tried displaying t.Job_Title and reloading the page it came up with undefined method ”Job’
Is there a way to display this column values? If I render it using xml I can see the Job-Title being displayed.
I know i can create an additional column in the view with a suitable jobtitle name but was interested to know if there was some way to deal with such situations.

thanks,

abhi

30 07 2008
nasir

Yes there is a way for this, instead of t.Job-Title, use t['Job-Title']

30 07 2008
abhi

thanks bud,

your a star…

cheers,
abhi

16 10 2008
Manik

Hey Nasir,

I never fancied using views in Rails. But I have a situation where I could try it and I am going to do that now after reading this post.

Thanks for the post

Manik
Blog
Company

25 11 2008
John Grimes

The problem that I have encountered with using views is that Rails has no language independent way of creating them, so it ignores the fact that it is a view and not a table when it generates the schema.rb file upon migration.
I use raw SQL (MySQL) to create the view in the migration, but the schema.rb file gets generated with code (create_table) that creates a table, not a view.
This screws up my tests because when the test database is generated from the schema.rb file, a table is created instead of a view, and as a result of this no data is accessible through that table.
I agree with you that views would be a really nice thing to be able to use in certain situations, but unless I can figure out a way to use them without screwing up the testing process I don’t think I will be able to use them.

Leave a comment