Buck
Buck

Reputation: 150

Managing users in Ruby on Rails (& ownership)

I'm somewhat of a Rails newbie, and am not quite sure what the convention is when tying users to their objects, such as documents. (And I now know how important it is to go with conventions in Rails)

So far, I have come up with 3 potential solutions in my head:

  1. Making every document essentially a child of every user, using has_many and belongs_to
  2. Giving every document an integer (user_id, or something along the lines of that) that ties it to the user. That way, whenever the user wants an index of their documents, I can identify all those that have the right ID.
  3. It seems like there's some plugins that do user management completely in their own way that doesn't fit into any of the above.

Additionally, I plan on using Devise for user authentication and management. From my understanding, that seems to be the most popular/widely used authentication gem -- please correct me if I'm wrong.

Upvotes: 1

Views: 571

Answers (3)

Richard Peck
Richard Peck

Reputation: 76774

I'm somewhat of a Rails newbie

Welcome to the club, although some people bite, most are totally cool.


tying users to their objects

You've already answered your own question...

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :documents
end

#app/models/document.rb
class Document < ActiveRecord::Base
   belongs_to :user
end

If a user creates a document, surely that would mean that you'd have to associate documents to users via a has_many / belongs_to relationship...

--

To give you some context, you'll have to add the user_id foreign_key to your documents table:

$ rails g migration AddUserForeignKeyToDocuments

#db/migrate/add_user_foreign_key_to_documents______.rb
class AddUserForeignKeyToDocuments < ActiveRecord::Migration
   def change
      change_table :documents do |t| 
         t.references :user, index: true
      end
   end
end

$ rake db:migrate

This would allow something like the following (using the current_user helper from Devise):

#config/routes.rb
resources :documents

#app/controllers/documents_controller
class DocumentsController < ApplicationController
   def create
      @document = current_user.documents.new document_params
      @document.save
   end

   private

   def document_params
      params.require(:document).permit(.....)
   end
end

If you're unsure about user authentication, you should go with Devise, although there are other authentication gems such as sorcery

Setting up Devise is simple:

#Gemfile
gem 'devise', '~> 3.5', '>= 3.5.3'

$ rails generate devise:install
$ rails generate devise User
$ rake db:migrate

#config/routes
devise_for :users

#app/controllers/documents_controller.rb
class DocumentsController < ApplicationController
   before_action :authenticate_user!
end

This will make it so only logged-in users can access /documents :)

Upvotes: 1

rob
rob

Reputation: 2296

you can use devise for authentification (or build an own login system there is a railscast and use cancancan for authorization. some defining of abilities you will find in the documentation just for example

can :update, Article

or if user can just delete own stuff

can :read, Project, active: true, user_id: user.id

i would also use the ActiveRecord relation with has_many e.g. and has_many through

Upvotes: 1

Kailan Blanks
Kailan Blanks

Reputation: 322

This is primarily an opinion-based question however I tend to see most projects using ActiveRecord's relations (e.g has_many, belongs_to).

Upvotes: 1

Related Questions