Good afternoon all!
Here's the background. I'm building a backend for a payment system. I want the canonical information for our Products and Plans to be on Stripe. As such I do not want to have a duplicated copy on our backend and pull them down from our RDB with ActiveRecord.
When someone calls for a list of Products or Plans I pull them down from Stripe, and then cache them. When we need to create/update/destroy them we make the API calls to Stripe and the webhooks trigger the updates.
I've not done something like this before, and normally just have an ActiveRecords model to CRUD.
Are there any best practices / methodologies to follow when doing something like this?
Thanks!
While it would be technically possible, I recommend against doing this in almost all cases. Your products are likely an integral part of your app. You will loose out on a lot of the idiomatic rails behaviors and abilities by trying to roll your own logic in this way. You'll also be coupling your app very tightly with a third party service that you in no way control.
I would seriously consider using standard AR backed models for this data in your app and taking the time to abstract out code that manages the YOUR APP <--> 3RD PARTY APP communication. This way your app is the canonical source of the information it manages, you get all of the rails' sugar, and you're in control in the event that you need to change back end providers.
Related
I'm building a system that (when completed) will serve multiple commercial customers. I need to accomplish the following:
App should use one database
Each commercial customer will have multiple users.
When any of the commercial customer's users create/read data, they should do so under the commercial customer's namespace....Thus they should not be able to see other customers' data and should also not be allowed to create data etc. for other customers.
Initially I thought that the best way would be to assign all users to a commercial customer via association. As I was worried about querying the database too much, I did some research and found some info regarding Rack and middleware. This seems to be another option of achieving what I want, but it confused me a little.
What is the best option to achieve this sort of functionality in my app?
**PS. All commercial Customers will have unique URL's ex. customer1.myapp.com
Thanks
Rack and Middleware are layers that requests go through before they hit the code you wrote in your Controllers and Models. In short, if you need some preprocessing, or anything of that nature going on, then you shouldn't mess with middleware. For this particular case, you don't need to deal with middleware.
You're building a standard Rails app that serves different clients (users, if you will). It is okay to make many queries to the DB. The important thing is to make sure your queries are efficient and that you're making proper use of the ActiveRecord system, which helps a lot in efficiency. You have Model#includes, Model#eager_load, amongst other methods at your disposal.
As for customer1.myapp.com, there is a lot of information in Rails guides about getting those things set up and interfacing with it.
What you're looking for is Multitenancy.
There are several approaches on how to implement it. One of the options is to use PostgreSQL's schemas.
You can take a look on the gem Apartment. Maybe you can get some idea out of it.
My friend has setting up a database for a Ragnarok Online server, and he wants me to code the relative website, which is going to use some of that data (and obviously, i'll have to add tables for the news system, website accounts, etc). Since i'm learning RoR i was going to do it that way.
I have a few "best practice" questions related to this :
Should I create a different database for the website, since it's going to have its particular data alongside the game data ? (i already have a few clues to link multiple databases with Rails, but that seems too much of a hassle for what it is).
If not, do i have to create Model/Controller for each of the tables composing the database, despite the fact that i'm not going to use 90% of it ? Or just the ones that i need ?
An example of this problem : the game database has its own "user" table, but i have to have another "user" table for the website, and do some Joins between those two. So, what's the best practice here ?
Uhm, best practice is not making your own user table. This will cause you much pain. Best practice? Use an API. Expose the game's database in some way to your website, and fetch that info with external requests in your web application.
The reason why making a second user table is a hassle:
1) You'll constantly have to update it, pulling data from the original
to keep it up-to-date.
And I mean furthermore, you're gonna have to create a CRON job or something pulling data from that original table to keep it up to date. Yuck. Also what if that CRON job makes a mistake? (It will)
2) It's almost inevitable that there will be inconsistencies if two
separate tables are maintained. Are you sure your web application is
really fail-proof?
Update:
What you're gonna need is essentially a second Rails application that acts as a REST API for that database. For a good idea of what REST is, I'd read through this to get you started: http://tomayko.com/writings/rest-to-my-wife
Once you have a good understanding of that, start making your app, and test if it's working by using tools like cURL to send requests to your API.
Once you have that done, I'd take a look into the Ruby rest-client gem like Nobita mentioned. This is what you're going to use from your web application to request information from your API application.
Just let me note, I think this would be a terrible first Rails project, unless you're already really well versed in other web development tools, preferably MVC frameworks.
Perhaps you can help me think this through to greater detail.
I need to build or make available a uri for a model instance that can be referenced or used by another application which may or may not be a rails application.
e.g.
I create a standard Post with content; I want to build a URL for that post another application can consume or reference by looking at the model in the database (or another less sticky fashion). Datamapper has a URI field, I want to build a canonical uri, store it there and have another application be able to access, announce, manipulate, etc.
Basically, I have several applications that may be in different places, that need to access the same model, to do differing things with the model. I need a way to make that happen clearly without putting them all in one monster application.
I've looked at Pubsubhub, RSS, etc. but haven't found any concrete examples of what I'm trying to do. Do I need to create an common API for the applications, etc?
DataMapper is very flexible about using existing databases.
Many people come to DataMapper because it can create and tear down the database structures without migrations. However, you do not have to work with it in that way.
I have had good success with using a large set of models owned by a central 'housekeeping' app and then declaring a small subset of the same models in separate 'interface' apps.
Some trial and error is required to figure out what works but it can certainly be done. I'd suggest putting your models in modules and including them across apps if possible.
A final point it sounds like you want URIs/URLs to be the primary interface. If that is the case I strongly suggest you look at Sinatra. It is entirely oriented around URLs (and I find Rails routes very obtuse).
I'm going to be collaborating with a Python developer on a web
application. I'm going to be building a part of it in Ruby and he is
going to build another part of it using Django. I don't know much about
Django.
My plan for integrating the two parts is to simply map a certain URL
path prefix (say, any request that begins with /services) to the Python
code, while leaving Rails to process other requests.
The Python and Ruby parts of the app will share and make updates to the
same MySQL datastore.
My questions:
What do people think generally of this sort of integration strategy?
Is there a better alternative (short of writing it all in one language)?
What's the best way to share sensitive session data (i.e. a logged in
user's id) across the two parts of the app?
As I see it you can't use Django's auth, you can't use Django's ORM, you can't use Django's admin, you can't use Django's sessions - all you are left with is URL mapping to views and the template system. I'd not use Django, but a simpler Python framework. Time your Python programmer expanded his world...
One possible way that should be pretty clean is to decide which one of the apps is the "main" one and have the other one communicate with it over a well-defined API, rather than directly interacting with the underlying database.
If you're doing it right, you're already building your Rails application with a RESTful API. The Django app could act as a REST client to it.
I'm sure it could work the other way around too (with the rest-client gem, for instance).
That way, things like validations and other core business logic are enforced in one place, rather than two.
A project, product, whatever you call it, needs a leader.
This is the first proof that you don't have one. Someone should decide either you're doing ruby or python. I prefer ruby myself, but I understand those who prefer python.
I think starting a product asking yourself those kind of questions is a BAD start.
If your colleague only knows prototype, and you only know JQuery, are you going to mix the technologies too? Same for DB? And for testing frameworks?
This is a never ending arguing subject. One should decide, IMHO, if you want so;ething good to happen. I work with a lot of teams, as a consultant, Agile teams, very mature teams for some of them, and that's the kind of stuff they avoid at all cost.
Except if one of you is going to work on some specific part of the project, which REALLY needs one or other of the technologies, but still think the other one is best for the rest of the application.
I think, for example, at a batch computing. You have ALL your web app in ror or django, and you have a script, called by CRON or whatever, computing huge amounts of data outside the web app, filling a DB or whatever.
My2Cts.
I was wondering if somebody has some insight on this issue.
A little background:
We've been using Rails to migrate from an old dBase and Visual Basic based system
to build internal company IntrAnet that does things like label printing,
invetory control, shipping, etc - basically an ERP
The Dilemma
Right now we need to replace an old customer-facing website that was done in Java, that
would connect to our internal system for our clients to use. We want to be able to pull information like inventory, order placement, account statements from our internal system and expose it to site live. The reason is that we take orders on the website, through fax & phone and sometimes we have walk-ins. So sometimes (very rarely thou) even a short delay in inventory update on our old Java site causes us to put an order on backorder, because we sell the same item to 2 customers within half an hour. It's usually fixed within one day but we want to avoid this in the future.
Actual Question
Does anyone have any suggestion on how to accomplish this in a better
way?
Here are three options that I see:
a) Build a separate Rails app on a web server, that will connect to the same DB that our internal app connects to.
+++ Pluses:Live data - same thing that our internal apps see, i.e. orders are created in real time, inventory is depleted right away
--- Minuses: Potential security risk, duplication of code - i.e. I need to duplicate all the controllers, models, views, etc. that deal with orders.
b) Build a separate Rails app on a web server, that will connect to a different DB from our internal app.
+++ Pluses: Less security exposure.
--- Minuses:Extra effort to sync web DB and internal DB (or using a web service like REST-API), extra code to handle inventory depletion and order # creation, duplication of code - i.e. I need to duplicate all the controllers, models, views, etc. that deal with orders.
c) Expose internal app to the web
+++ Pluses: all the problems from above eliminated. This is much "DRY"er method.
--- Minuses: A lot more security headaches. More complicated login systems - one for web & one for internal users using LDAP.
So any thoughts? Anyone had similar problem to solve? Please keep in mind that our company has limited resources - namely one developer that is dedicated to this. So this has to be one of those "right" and "smart" solutions, not "throw money/people/resources at this" solutions.
Thank you.
I would probably create separate controllers for the public site and use ActiveResource to pull data from you internal application. Take a look at
http://blog.rubybestpractices.com/posts/gregory/rails_modularity_1.html
http://api.rubyonrails.org/classes/ActiveResource/Base.html
Edit - fixed link and added api link
I would go for a. You should be able to create the controllers so that they are re-usable.
Internal users are as likely to duplicate data as external users.
It's likely that a public UI and an internal, for-the-staff, UI will need to be different. The data needs to be consistent so I would put quite a bit of effort into ensuring that there is exactly one, definitive database. So: one database two UIs?
Have a "service" layer that both UIs can use. If this was Java I would be pretty confident of getting the services done quickly. I wonder how easy it is in Ruby/Rails.
The best outcome would be that your existing Customer Java UI can be adapted to use the Rails service layer.
Assuming you trust your programmers to not accidentally expose things in the wrong place, the 'right' solution seems to me to have a single application, but two different sets of controllers and views, one for internal use, and one for public-facing. This will give you djna's idea of one database, two UIs.
As you say having two separate databases is going to involve a lot of duplication, as well as the problem of replication.
It doesn't make sense to me to have two totally separate apps using the same database; the ActiveRecord part of a Rails app is an abstraction of the database in Ruby code, therefore having two abstractions for a single database seems a bit wrong.
You can also then have common business rules in your models, to avoid code duplication across the two versions of the site.
If you don't completely trust your programmers, then Mike's ActiveResource approach is pretty good - it would make it a lot harder to expose things by accident (although ActiveResource is a lot less flexible and feature rich than ActiveRecord)
What version of Rails are you using? Since version 2.3 Rails Engines is included, this allows to share common code (models/views/controllers) in a Rails plugin.
See the Railscast for a short introduction.
I use it too. I have developed three applications for different clients, but with all the shared code in a plugin.