I have an existing oracle database with triggers when a record is created. The documentation indicate to register evenlisteners for update and create. Do anybody know best practice.
What happens after or before the record is created when you use triggers is totally dependent of the db that you're using. As #aldrin says, it will help consistency if there's another application handling the same database.
I suggest you to use the events if there're plans to support more than one database vendor because you avoid the work to translate triggers between them.
If you are asking if Oracle triggers can be replicated in grails - the answer is that the event binding can be replicated (see http://grails.org/doc/latest/guide/GORM.html#eventsAutoTimestamping). as far as, what you are doing in PL/SQL for the trigger logic, that might not translate as easily.
Related
I would like to disable my rails application's oracle database partitioning, but :
I don't know how to tell whether my app is using database partitioning
I don't know how to find the place my app use partitioning, since I didn't write most of the application's code myself
Can I just system search the code base for the keyword 'Partition' and look for any result that has the key word partition in raw SQL statement?
How should I go about this?
Thanks!
Update:
I have 2 answers below and they seem to understand my question differently
I am confused now as well. I want to disable the partition feature of my Oracle Database (https://www.oracle.com/technetwork/database/options/partitioning/overview/index.html), does that means I cannot use the 'partition by' keyword (Oracle "Partition By" Keyword) anymore?
Partitioning is done at the schema level declaratively. Usually, one would not expect the application code to directly need anything specific to use partitioning since it is done at the data definition level. You can connect to the schema owner account and check the data dictionary views USER_PART_TABLES for partitioned tables owned by the user and USER_PART_INDEXES for the indexes.
I'm creating a new rails APP that's works with the same postgres DB as my API.
The API and the APP has a couples of common models.
Exemple :
The API and the APP has a Connection model
The APP will create a simple connection in the DB and the API will do the rest (like handler using the connection for many things )
So I wanted to use Hair Trigger that allowed to trigger a DB insert, or update and like it to a DB behavior that's will be execute.
But I would like to execute a method from one of my helpers.
like that :
class Connection < ActiveRecord::Base
trigger.after(:insert) do
SomeObject.method()
end
end
I can't use after_create because the creation action is not done on the same server (but same DB)
any ideas ?
Thanks !
The reason why Hair Trigger only supports SQL is that it's purpose is to help you maintain database triggers (https://www.postgresql.org/docs/9.6/static/sql-createtrigger.html).
Database triggers are decoupled from your application and will only be able to trigger SQL inside your database. It won't actually be able to trigger any code inside of your application.
A solution to your problem would be to use events. If you ever worked with Javascript you might have come across Event and EventListener before. The purpose of events is to decouple your code. One part of your application sends an event when an action has been taken e.g. Something was inserted into the database. Other parts, as many as you like, of your application can then subscribe to these events and take the actions necessary.
Since you are working with Rails I would suggest you to take a closer look at the Wisper gem (github.com/krisleech/wisper). If your App and API; like you are describing, lives in different processes (or servers), you should look into using a background worker to handle the events asynchronously. A common approach to this is to use Sidekiq Wisper (github.com/krisleech/wisper-sidekiq) that enables you to trigger the events async using Sidekiq as your background worker.
For a good introduction to the subject, here's a guide to get you started (I'm not the author): http://www.g9labs.com/2016/06/23/rails-pub-slash-sub-with-wisper-and-sidekiq/
There might be easier ways to solve the issue you are facing but you will need to post some more details on the use case for us to give you some better pointers.
I'm using couchrest_model to manage some DBs in Rails. So far, it worked like a charm, but I noticed that if I PUT some data via HTTP request, CouchRest Model doesn't seem to realise that the changes are made, so it wipes off the whole record. Of course, I can see the changes in Futon, but not in Rails. When I enter the console, the previously saved instance is just not there.
Of course, I could use HTTP all the way, but I'd really like to make use of validations and other goodies that are available in ActiveRecord class.
Is there any chance that I can make these two guys work together?
P.S.
If you think/know that this approach will work with any other CouchDB Ruby/Rails gem, please, do tell! =)
I've mentioned CouchRest Model because IMO it's the most up-to-date and advanced gem out there.
I realised that this one was so damn easy, it's just that I was using the wrong tool (apart from being a proper n00b). AFAICT, it's not possible to use CouchRest Model solely to carry out persistent operations on CouchDB backend. All external calls that alter the database record(s) in certain way will somehow "remove" that record from ActiveARecord. Instead, you'd probably like to use CouchPotato, since it supports persistent operations.
I'll be glad to give checkmark if anyone comes up with vaguely better idea that this one.
Let's say your app enables users to create their own tables in the database to hold their own, custom data. Each table would have it's own schema. What are some good approaches?
My first stab involved dynamically creating migration files and model files bu I'd like to run this on heroku where you can't write to the filesystem.
I'm thinking eval may be the way to go to create and run the migration class and the model class. But I want to make sure the model class exists when a new process of the app is spawned. Can probably do this by storing these class definition with each user as they create new tables and then run through them all at startup. But now it's convulted enough that I may be missing something obvious.
It's probably a better idea not to generate new classes on runtime. Besides all of the security risks, each thread's startup time will be abominable if you ever get a significant number of users.
I would suggest rethinking your app design and aim at generic tables to hold the user's custom data. If you have examples of data structures that users can create we might be able to help.
Have you thought about a non-sql database for those tables? Look at CouchDB - there are several plugins on Github that integrate it with rails. Records in the database are JSON documents, with arbitrary key-value structure. May be perfect for a user-defined schema.
There is (was?) a cool Wiki project, called Informl. It was a Wiki, not just for web pages but for web applications. (Get it? It's informal because it's a Wiki, it's got forms because it is an application, and it's user-generated, thus Web 2.0, which means that according to an official UN resolution it is legally required to have a name which is missing a vwl.)
So, in other words, it was not just about user-generated content, but also user-generated structured data.
They did this by generating PostgreSQL-specific SQL at runtime to create new tables and then have ActiveRecord reload the schemas.
The code is up on RubyForge. It's based on Rails 1.2.3. I guess you could do much better than that today, especially with the upcoming extensibility interfaces in Rails 3.
What's the best practice way for keeping track of who did what in a mid-sized Rails app? Intercepting all database read/writes and storing that in another table?
you can pretty simply adapt acts_as_versioned to also record information about which user performed the operation. I'd suggest looking into that plugin as versioning is rarely a bad idea.
You can use Observers on callbacks like create/update/delete for several models and save data to another table/model but if you want to have a wiki-like site - acs_as_versioned is better option.
If you'd like to "roll your own" solution you can implement database triggers on insert/update/delete that update a separate table. Otherwise there are several commercially supported data audit applications that can be purchased and configured to track and report on these activites for you at the database level.
Rather than reimplementing, you should try some plugins like acts_as_audited
acts_as_audited is an ActiveRecord extension that logs all changes to your models in an audits table.
or PaperTrail.
PaperTrail lets you track changes to your models' data. It's good for auditing or versioning. You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.
Whichever suits your needs.