I'm trying to use a specific DB on a whole model. Basically, we have a master/slave DB configuration, and I want to do using(:master) on whole order-related methods (so on the whole order model).
The thing is that I can apparently do using(:master) at the top of my model, but I'm unsure about what it does and I cant find it in the doc:
Will all the calls in the model use master (like, if a method does User.find in this model, will it use master?)
or
Will all the calls all across the app for the Order methods use master (like, if a method in the User model does Order.find, will it use master?)
Thanks for the explanation.
Here is how we did it.
We made the master connection the same as the default database defined in the database.yml.
Then in each of the models that live in master we would put the following line right below the class line.
octopus_establish_connection Rails.env.to_sym
I am new to ruby and rails and I am having difficulty conceptualizing the MVC techniques in conjunction with database views. I am dealing with a legacy database that has several viiews that are used to generate reports.
Where I get lost is how do I actually use a database view. Should it be put in a model? If so what exactly would that look like?
As an example the legacy db has a view called qryTranscriptByGroup. It is used in the legacy application in an SQL statement such as "SELECT * FROM qryTranscriptByGroup WHERE group='test_group'". This returns a small number of records usually less than 100.
If i create a model, Transcript, how would I define a method like Transcript.find_by_group(group)? As well, it would seem that I might need to prevent any other "find" methods as they would be invalid in this context.
There is also the the fact that the view is read-only and I would need to prevent any attempts to create, update or destroy it.
Perhaps I am going about this entirely the wrong way. The bottom line is that I need to get information from several tables (models?) that represent the information about a user (a transcript). Actually one or more users (transcripts plural).
-Thanks!
You can use a database view like a normal model.
In your case:
class Transcript < ActiveRecord::Base
set_table_name "qryTranscriptByGroup"
set_primary_key "if_not_id"
end
The query will be then:
Trascript.find_by_group('test_group')
without you need to declare anything.
Rails uses the method_missing method to magically generate find_by_column_name methods.
For the create/update/delete action you can simply delete them or not create them in the controller.
Let's say I'm within a rails project in some model named Apple.
I'm going to switch databases to another server so I'll call: ActiveRecord::Base.establish_connection()
I want to access the table 'Banana' in this particular database. I can see that the table exists by calling table_exists?
However, I'm not sure how to access the table... I want to just be able to do something like Banana.find(:all)
How should I work this out?
Have you tried connection_ninja gem? Pretty handy for multi-db connections:
https://github.com/cherring/connection_ninja
I have a standard rails application, that uses a mysql database through Active Record, with data loaded through a separate parsing process from a rather large XML file.
This was all well and good, but now I need to load data from an Oracle database, rather than the XML file.
I have no control how the database looks, and only really need a fraction of the data it contains (maybe one or two columns out of a few tables). As such, what I really want to do is make a call to the database, get data back, and put the data in the appropriate locations in my existing, Rails friendly mysql database.
How would I go about doing this? I've heard* you can (on a model by model basis) specifiy different databases for Rails Models to use, but that sounds like they use them in their entirety, (that is, the database is Rails friendly). Can I make direct Oracle calls? Is there a process that makes this easier? Can Active Record itself handle this?
A toy example:
If I need to know color, price, and location for an Object, then normally I would parse a huge XML file to get this information. Now, with oracle, color, price, and location are all in different tables, indexed by some ID (there isn't actually an "Object" table). I want to pull all this information together into my Rails model.
Edit: Sounds like what I'd heard about was ActiveRecord's "establish_connection" method...and it does indeed seem to assume one model is mapped to one table in the target database, which isn't true in my case.
Edit Edit: Ah, looks like I might be wrong there. "establish_connection" might handle my situation just fine (just gotta get ORACLE working in the first place, and I'll know for sure... If anyone can help, the question is here)
You can create a connection to Oracle directly and then have ActiveRecord execute a raw SQL statement to query your tables (plural). Off the top of my head, something like this:
class OracleModel < ActiveRecord::Base
establish_connection(:oracle_development)
def self.get_objects
self.find_by_sql("SELECT...")
end
end
With this model you can do OracleModel.get_objects which will return a set of records whereby the columns specified in the SELECT SQL statement are attributes of each OracleModel. Obviously you can probably come up with a more meaningful model name than I have!
Create an entry named :oracle_development in your config/database.yml file with your Oracle database connection details.
This may not be exactly what you are looking for, but it seems to cover you situation pretty well: http://pullmonkey.com/2008/4/21/ruby-on-rails-multiple-database-connections/
It looks like you can make an arbitrarily-named database configuration in the the database.yml file, and then have certain models connect to it like so:
class SomeModel < ActiveRecord::Base
establish_connection :arbitrary_database
#other stuff for your model
end
So, the solution would be to make ActiveRecord models for just the tables you want data out of from this other database. Then, if you really want to get into some sql, use ActiveRecord::Base.connection.execute(sql). If you need it as a the actual active_record object, do SomeModel.find_by_sql(sql).
Hope this helps!
I don't have points enough to edit your question, but it sounds like what you really need is to have another "connection pool" available to the second DB -- I don't think Oracle itself will be a problem.
Then, you need to use these alternate connections to "simply" execute a custom query within the appropriate controller method.
If you only need to pull data from your Oracle database, and if you have any ability to add objects to a schema that can see the data you require . . . .
I would simplify things by creating a view on the Oracle table that projects the data you require in a nice friendly shape for ActiveRecord.
This would mean maintaining code to two layers of the application, but I think the gain in clarity on the client-side would outweigh the cost.
You could also use the CREATE OR REPLACE VIEW Object AS SELECT tab1., tab2. FROM tab1,tab2 syntax so the view returned every column in each table.
If you need to Insert or Update changes to your Rails model, then you need to read up on the restrictions for doing Updates through a view.
(Also, you may need to search on getting Oracle to work with Rails as you will potentially need to install the Oracle client software and additional Ruby modules).
Are you talking about an one-time data conversion or some permanent data exchange between your application and the Oracle database? I think you shouldn't involve Rails in. You could just make a SQL query to the Oracle database, extract the data, and then just insert it into the MySQL database.
I have just started Rails and have a basic question.
I need to add customer properties(like email id etc) so that the Rails app can read them at runtime. How can I do this ?
Can I add them to development.rb and if so how can I read it ?
In java I would have created a properties file and read it from my app.
thank you,
firemonkey
Are you trying to do store and load configuration settings?
It's easy to store configuration settings in a yaml file and load them with initializers - loads better than littering your environment files.
This Railscast: http://railscasts.com/episodes/85-yaml-configuration-file shows you how.
I'm not sure exactly what you are asking. I'm guessing you want an initial set of data in the database that you can access when you actually run the app? If that is so check out this other SO question How (and whether) to populate rails application with initial data
It's a little unclear exactly what you're trying to do, but it sounds like maybe you have a model called Customer and you would like to add some attributes to it, such as email address, id, and so on?
Basically, with Active Record you don't need to do anything special to add a simple attribute (like a string or an integer). Just add a field called "email_address" to your customers table in the database, and all of your Customer objects will automagically get "email_address" and "email_address=" methods (not to mention the Customer class itself getting "find_by_email_address" and other useful methods as well). If you are adding a field containing another model, it's a bit more complicated - add a "something_id" field to the table, and an association to the class definition (eg, "has_one :something"). For more information, see the ActiveRecord api documentation.
You don't have to use any particular means to add the field to your database, but you might want to consider Migrations. Migrations are a convenient way to keep your schema versioned and synchronized across multiple machines.
If you are building your model right now, there's a short cut built in to the generator to add fields. Instead of just saying...
script/generate scaffold customer
...you can say...
script/generate scaffold customer email:string name:string badge_number:integer
...and it will generate all the appropriate fields in your migration, as well as adding them to your generated views.