Remote data model in Rails - ruby-on-rails

i have model with validations, some methods, filters and so. Unfortunately the data are from API, so i need to overload the method which is pull the records from DB. Which method is that?
So far i have creation. Method create in active record's model is presisting new record. I just add method create to my model and it's creating records over the API. Now i want it for selecting the data.
Following code is example of what i already have (creation of records):
def create
EmployeesApi.create(self.attributes.reject{|k,v| %w(id created_at updated_at).include? k })
end
I need it as low level as possible, because it has some relations and app specific validations. Moving also the relations and surrounding logic would mean integrate two existing systems and that's not ok in this case.
Another explanation:
I want to bypass the database for data of the model, but for association let everything as it was. The model's data are stored in another app/database/system.
I'll load model's own data by API and ActiveRecord will pair/load it's associations from local DB

If EmployeeApi would be modeled after ActiveResource you could possibly enhance it with ActiveModel. Associations might work only in one way (from ActiveRecord to ActiveResource). It is also good to consider exceptions such as API is down.

I think what you are trying to achieve is to pull some data from the DB before creating this record? or validate some DB field, maybe ensure a unique constrain or something.. Please look into the active record hooks/callbacks
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
You can do something like this:
class Subscription < ActiveRecord::Base
before_create :record_signup
private
def record_signup
self.signed_up_on = Date.today
end
end

Related

Create a model association where the model is not a active record model rails

I have a model called Client.
This extends not from ActiveRecord::Base but from my own wrapper class.
These objects are not stored in my own database.
I have some other models called Answer and Device for example. These are stored in my database with a client_id.
Now, what I want to do is that is can call Answer.client and Client.answers for example. The normal way would be with ActiveRecord associations but that doesn't work is this case.
I can define my own .answers and .client method but in my opinion that's not the way to go with Rails.
Thanks in advance for replying!

Update attribute with array insertion

I have an Impression model with an actions attribute that is serialized for Array.
class Impression < ActiveRecord::Base
serialize :actions, Array
end
Normal attribute updating procedure:
impression.update(some_attr: "new_value")
Normal array insertion procedure:
impression.actions << "new_value"
impression.save
Is there a way to insert a new value to an array attribute that works like the .update method, i.e. in one single expression?
No, this is not possible when using the ActiveRecord serialization feature because the serialization/deserialization must be controller by ActiveRecord and update performs a direct SQL update call on the database.
Some non-relational database (such as MongoDB) offers this feature because they are designed in order to do so. PostgreSQL provides a Hash extension you can install that would allow you to perform direct operations on the serialized field.
In all the other cases, you could potentially update the field directly, but I don't encourage you to do so. There is a potential risk to write corrupted data.
Instead, I suggest you to create a custom method that performs both the push and save. In any case, this is a good idea because you are exposing a custom API outside the model instead of coupling your model to the ActiveRecord architecture.
class Impression < ActiveRecord::Base
serialize :actions, Array
def add_action(action)
self.actions << action
self.save
end
end
The you can use
impression = ...
impression.add_action "new_value"

Should I create model files when only visualizing data in Rails?

I started working on first small rails project which will in fact get data from database and visualize in jquery datatable. There will be no updates at all. The question is, should I create models for this data and access it through activerecord or it is ok to access it directly through SQL commands in controller ?
You should still make models to keep the controller clean.
Rails pattern is that all data access should be done through the models. You don't necessarily have to have any update/insert logic or even inherit from ActiveRecord, but that's where readers of your code would expect to find the data access.
Furthermore, you will need to pass some sort of object to your views, and it makes the most sense to use a model rather than a throw away temp object. This way you can cleanly change the model and only have one place to update.
For example, say you later need to add a full_name attribute to your report. If you had straight SQL in the controller and you were just passing the query results to the view, you'd have a harder time concatinating first_name and last_name. But with a model, you can just add
def full_name
"#{self.first_name} #{self.last_name}"
end
in one place, and all the controller actions that show that report now have a full_name property.
If you plan to do testing, having a model class makes that a heck of a lot easier as well. You can test the model without having to get the controller involved.

Aggregating Data in Rails 3

I want to aggregate data from different sources, Twitter lastfm and that sort. I just can't figure out how to store the data. Clearly in a database but I can't figure out how abstract to make the table to hold all this data without compromising the logical understanding of the data in each column.
I was wondering if anybody else had experience with this and now they tackled it in rails.
One option, if you want to stick with SQL, would be to have a Model/Table which contains fields common to every data source (title, url, summary) which is associated to other Models/Tables which contain the fields specific to individual data sources. The associations could be regular or polymorphic. And if you wanted to get in to some metaprogramming you could use method_missing to delegate method calls for fields not present in the 'common' Model to the associated models. This would work best with a polymorphic join. Psudeo-code:
class DataSource
belongs_to :data_source_extension, :polymorphic => true
def method_missing(method)
if data_source_extension.responds_to? method
data_source_extension.send(method)
else
super
end
end
end
The other option would be STI, so one table with all fields and a 'type' field which tells Rails which model the record should be wrapped in. This depends on how many different sources you have and how different they are from each other.
If the fields don't need to be searchable storing a Hash in a Text field works well. See Serialize and the attr_bucket gem.
Or if you want to trendy a NoSQL type database allows on-the-fly fields to be generated.
What you need is a document-oriented database (I recommend you MongoDB), and then having a set of adapters, one for each type of provider.
Document oriented database

Rails 3 Polymorphic Association between one MongoMapper model and one/many Active Record model/s

I have a Record model (Active Record) that stores some custom logs.
Record is in polymorphic association with all the other model in my app, and I can effectively log what I want hooking my Record methods in the other controllers.
What I need:
To have the logs in a separate database.
So I have to:
Be able to manage two different databases in my apllication (one is Postgres/ActiveRecord and the other one is MongoDB/MongoMapper)
Generate a polymorphic association between my Record model, now with MongoMapper, and the rest of my Active Record models.
That way I can persist my logs to the MongoDB database.
Thanks.
Yes this can be done.
To create a polymorphic association you need both the class and an id. Idiomatically the fields will be named <assoc>_type and <assoc>_id‡. You will need to do some wiring up to make everything work.
Create a MongoMapper::Document Class with the keys <assoc>_type and <assoc>_id with the correct types (I believe MongoMapper allows Class as a key type) along with any other keys you may need.
Define the method <assoc> and <assoc>=
def assoc
assoc_type.find(assoc_id)
end
def assoc=(input)
assoc_type = input.class #STI makes this more complicated we must store the base class
asspc_id = input.id
end
Possibly add a method to your ActiveRecord models allowing them to access you MongoMapper logging class. If there are a lot, you may want to build a module and include it in all the classes that need that kind of functionality.
‡ replace with something meaningful for you application like 'reference' or 'subject'

Resources