sternze
sternze

Reputation: 1644

Rails has_many through default values ActiveRecord

Currently I'm developing an app, that covers some very basic document management. During this, a question popped up.

Here is the scenario:

I have a classical many-to-many relationship for User and Document (A user can download many documents and a document can be downloaded by many users).

Inside this application there are "public documents" which should be accessible by everyone.

The obvious (and naive) solution here is to add the "public documents" to the mapping table for each new user. But this is really naive, and I don't want to write a routine that inserts those elements into the mapping table, which would also waste database storage.

Question

Is there a way in Rails to add those public documents (which are marked via a flag) to the users downloadable documents in ActiveRecord?

Example:

Documents

Id   |   Name   |   IsPublic
------------------------------
1    |   Test   |   false
2    |  Public  |   true

Users

Id   |   Name
--------------------
1    |   sternze

Downloadable Documents:

User_id   |   Doc_id
----------------------
   1      |      1

What I want to be able to do now is the following:

@user = User.find(1)
@user.documents  # -->  now contains documents 1 & 2
# I don't want to add rows to the documents inside the controller, because the data is dynamically loaded inside the views.

My Associations are the following:

class User < ApplicationRecord
  has_many :downloadable_documents
  has_many :documents, through: :downloadable_documents
end

class DownloadableDocuments < ApplicationRecord
  belongs_to :user
  belongs_to :document
end

class Document < ApplicationRecord
  has_many :downloadable_documents
  has_many :users, through: :downloadable_documents
end

I was not able to find an easy way to accomplish what I want, but maybe I overlooked something.

Upvotes: 1

Views: 314

Answers (1)

SteveTurczyn
SteveTurczyn

Reputation: 36860

create a scope in documents for public documents

class Document
  scope :public, -> {public?}
end

create a user method 'all_documents'

class User

  def all_documents
    documents + Document.public
  end

end

Then use all_documents in your iterations instead of documents

Upvotes: 3

Related Questions