Rails implementation of a database-based file system - ruby-on-rails

Because "file system" and "rails" are such common topics both together and separate I fail to find any Ruby on Rails open source app that implements a file system in the database. I would like to use such an application as a starting point or template.
I've already been able to implement the User and the Directory models (using Ancestry for the latter), and I'm on my way for the File model (my app only requires one kind of file).
class User < ActiveRecord::Base
attr_accessible :email, :name, :password, :password_confirmation
has_secure_password
has_many :directories, dependent: :destroy
# ...
end # class User
class Directory < ActiveRecord::Base
attr_accessible :name, :parent_id
has_ancestry
belongs_to :user
has_many :files, dependent: :destroy
# ...
end # class Directory
# not actually implemented, yet
class File < ActiveRecord::Base
attr_accessible :name
belongs_to :directory
# ...
end # class File
In views I'm using jsTree to present the tree and a form to add/delete, edit, ... This will need to change into using AJAX because redirecting back to same page does not preserve the expanded/collapsed state of the tree.
However I have this nagging feeling that I'm doing something that has already been done lots of times. Can you please provide links to such application(s) or give hints about implementing both the model part and the view part?

Hints about implementing the model part
To get model to be organised as a tree structure the tecnique is know as Nested set model therefore a common name (helpful to googling etc. ) could be "Activerecord nesting" ;-)
Your choice about Ancestry is welcome but you can benefit having a look at projects (mix-in,plug-in,...) like:
awesome_nested_set
act_as_nested_set
Better nested set
act_as_a_tree
Closure Tree
Arboreal
For the file upload 'n store part I would suggest , in addition to the already mentioned Paperclip, to look at carrierwave by itself provides a storage based on the "fog" gem (supports storing files with AWS, Google, Local and Rackspace ) but you can opt for database (e.g. sqlite) storage leveraging carrierwave-activerecord
Hints about implementing the view part
About "views" you might be interested in this answer about jQuery File Tree a configurable AJAX file browser plugin for jQuery and dnamique blog which has a rails connector for this plugin and sources and demo about it.
as an alternative, look at the implementation (sources) of the applications mentioned in next section.
Links to such applications
Here some "File manager" of interest:
Boxroom
Saphyra (available as mountable engine)
rails based CMS might have code of some interest

I think you're on the right track. Your Directory and File models look fine to me.
Your nagging feeling is partly correct. It's a common requirement to support uploading and storing files, but it's not that common to model and display an entire hierarchal directory structure.
You may want to reconsider actually storing the files in the database. This is usually a bad idea. Since files are such variable sizes, they can bloat your table and hurt performance. I recommend storing your files in Amazon S3. This is much more reliable and fast storage, and you can serve S3 urls directly to clients to reduce bandwidth and load on your own servers. You can use the paperclip gem to handle file uploads and store the files either on disk or on S3.

Related

dropbox clone - To use Active Storage directly on User Model or Have a separate Model handling the file attachment?

I'm building an app similar to Dropbox's concept where file storage is the key feature. It struck me when I started planning the app as to whether I should:
Have a User Model with has_many_attached to handle all files/images related to a user
Have a UserFile Model with has_one_attached and belongs_to :user
Still a rookie here, and I guess my concern is that I'm not sure if option 1 will have more limitations as the database grow in the future and accessing, storing, viewing, updating, and deleting any files belonging to the user may not be as flexible.
Also, additional tracking on the file is required, i.e. download counter, document verified etc.
Looking at option 2, it is definitely working but it makes the flow more complex and definitely will be difficult to maintain down the road.
Thanks in advance for your input.
Have search for stackoverflow and even rails guides but there is no information that I can see that helps me on this decision. At least, perhaps i cannot understand them.

want to give access for many organsation

We are developing a online rails application for schools, but we want to separate that all schools to each other.
Like slack website that manage many organisation from one application and organisation only access that data.
Also like trello, they also separate organisations in one application.
So what is the best approach is use for such type of application?
How we implement this in our ruby on rails application,that we separate all schools in our Database?
Okay.
Multi Tenancy
If you're coming from the world of "native" software, you'll be best reading up on multi tenancy:
(source: theenterprisearchitect.eu)
Rails apps are multi tenant by virtue of them running through a network; they run a single instance of an app, which is then accessible to anyone on that network (remember, the Internet is a huge network).
Rails provides all the functionality you mentioned above, with the added benefit of having a lot of world-leading companies using it to run (Twitter, AirBnb, Groupon etc have all famously used Rails).
You need to read up on database system design for your application, specifically...
MVC
To better understand how you'd make an application like you referenced, you need to understand the MVC (Model View Controller) programming pattern, and it's value within the world of object-orientated system design, especially pertaining to Rails:
Rails, like many other frameworks, uses MVC to build objects. These objects are defined by the programmer, but basically allow you to create the relevant data required to provide functionality to an application like you mentioned.
Specifically, each time you access a Rails app - you'll be essentially manipulating objects filled with data from the db. I'll explain any specifics in an update if you need it.
In regards your question, the way to integrate multiple organizations/entities into a single application is to set up the database schema to manage the organization as the "parent", with users and data as extra elements:
#app/models/company.rb
class Company < ActiveRecord::Base
has_many :users
has_many :invoices
has_many :clients, through: :invoices
end
#app/models/user.rb
class User < ActiveRecord::Base
belongs_to :company
has_many :invoices
end
#app/models/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :company
belongs_to :user
has_many :clients
end
This will give you the ability to use something like the following:
#config/routes.rb
constraints Account do
root "invoices#index" #-> http://company.url.com
resources :invoices #-> http://company.url.com/invoices/3
end
#lib/account.rb
class Account
def matches?(request)
Company.exists?(request.subdomain)
end
end
You'd then be able to use Devise to sign the user into the organization, allowing them to add / edit invoices as they need.
Each time you edit or update an invoice, a user will be assigned to it, allowing you to determine who created it etc.
Without going deeper into the code, that's what I think you need to know.
As concern of database design, you can design something like:
You should manage a organization model where each organization must be a sub-domain and your other model like User etc.. should be associate with organization model.You can extract the subdomain name from request url (like request.host, request.subdomain etc..) and find the records as per this subdomain request.
As concern of resource permission you can use cancan gem where you can manage resource accessibility through a single file.
https://github.com/CanCanCommunity/cancancan
Hope it is helpful for your initial design.

crossing the rails learning and development barrier from forms to more intesting objects

I've mostly been learning rails building crud applications for data entry and retrieval. I want to move on to the next level by creating an app with more interesting objects than just forms. I have been using form_for helper method throughout learning rails. I no longer want to create forms! My previous apps have been users signing up and writing microposts etc. I want to build a more fancy app like users creating charts for example.
Here is the idea I am trying to implement:
User's will have the ability to build dashboards. Each of the several dashboards the user can own will have various data visualization charts in them. So here is my model.
class Dashboard < ActiveRecord::Base
attr_accessible :name
belongs_to :user
has_many :comments, :dependent => :destroy
has_many :charts, :dependent => :destroy
end
Here is the routes file:
resources :users do
resources :dashboards do
resources :comments, :chart
end
end
How can I advance past the stage of dashboard_id and chart_id being displayed in view for a user? The user should be able to create dashboards and fancy charts. I know one thing for sure, I no longer need the form_for method. So what do I use to build such an app?
Thanks a ton in advance.
From what I can understand I think you would want to visualize your data as graphs. There are several javascript libraries that allow for data in DOM to be visualized as interactive graphs which you can manipulate too !
I personally liked ChartJS (http://chartjs.devexpress.com/) , you might want to take a look.
All you need to do is fetch data from your models using appropriate controller and place them in the right containers ( as configured by you using ChartJS or your javascript of choice)
You make visualize data as pie charts, bar graphs, line charts etc. using the same.
Hope this answer helped you.
Does the remainder of my design require frontend work?
Yes. You need also to work with the frontend for the design of the dashboard etc...
Look into some Javascript Frameworks like BackboneJS , AngularJS or TodoMVC, which demonstrates the same application across a variety of MVCs. as what Ben suggested.
Thank You !

Rails 3: how to use active record and mongoid at the same time

I read alot that folks recommend using nosql together with sql datastores. For example have some reporting audit-trailing or log information in mysql and some threaded hierarchical data in mongodb.
Is it possible to hook up rails with active record on mysql as well as mongoid?
Out of the box it seems not to work...Any hints?
Or is this a not recommended approach?
Well, to do it, you're supposed to leave Rails intact, so don't exclude libraries like it's commonly suggested in Mongoid documentation. You need to configure them separately, so you need to have a database.yml and mongo.yml config files and you need to make sure they're both getting loaded.
After that, you can enable/disable AR and Mongoid on a per-model basis.
class User < ActiveRecord::Base
#this is an AR model
end
class Item
include Mongoid::Document
#this is a Mongoid model
end

MongoDB, Carrierwave, GridFS and prevention of files' duplication

I am dealing with Mongoid, carrierwave and gridFS to store my uploads.
For example, I have a model Article, containing a file upload(a picture).
class Article
include Mongoid::Document
field :title, :type => String
field :content, :type => String
mount_uploader :asset, AssetUploader
end
But I would like to only store the file once, in the case where I'll upload many times the same file for differents articles.
I saw GridFS has a MD5 checksum.
What would be the best way to prevent duplication of identicals files ?
EDIT:
In fact, on my website the users would be able to upload files.
But to avoid to store multiple of identical files, I would like to just make links throught an association table. Nothing of difficult, but how to do this the libraries specified below.
If you have any idea.
Thanks
De-duplication may very well be a worthy goal depending on your application, but my first instinct to approaching this problem would be to turn it around -- why do you expect a lot of duplicate uploads? Can you reduce that likelihood so that users don't have to spend needless time uploading and you don't have to spend needless effort processing checks for duplicates?
What if you create an Asset model and attach the uploader to that, then an Article references_one :asset, and you let users choose from already available assets when creating a new article or upload a new one if needed?
I may not understand your application domain if you're giving a simplified example (please explain further if so), and it's certainly possible that duplication could still be a real issue, but I'd start by asking why significant duplication is expected, and next gather some data about how much of a problem it really is in your app and dataset before expending a lot of effort to address it.

Resources