1- # EctoIrs
1+ # EctoIRS
22
3- ** TODO: Add description**
3+ [ ![ Hex.pm] ( https://img.shields.io/hexpm/v/ecto_irs.svg )] ( https://hex.pm/packages/ecto_irs )
4+ [ ![ Documentation] ( https://img.shields.io/badge/docs-hexdocs-blue.svg )] ( https://hexdocs.pm/ecto_irs )
5+
6+ EctoIRS is an Elixir library that provides easy auditing capabilities for Ecto schemas and migrations. The library allows developers to automatically track who created or modified database records.
7+
8+ ## Features
9+
10+ - 🔍 ** Automatic Audit Fields** : Automatically add ` inserted_by ` and ` updated_by ` fields to your schemas
11+ - 🗃️ ** Migration Helpers** : Easy-to-use migration functions for adding audit columns
12+ - ⚙️ ** Flexible Configuration** : Customize field names, references, and behavior
13+ - 🚀 ** Auto-population** : Support for automatic field population via MFA tuples
14+ - 📦 ** Zero Dependencies** : Built on top of Ecto with minimal external dependencies
415
516## Installation
617
7- If [ available in Hex] ( https://hex.pm/docs/publish ) , the package can be installed
8- by adding ` ecto_irs ` to your list of dependencies in ` mix.exs ` :
18+ Add ` ecto_irs ` to your list of dependencies in ` mix.exs ` :
919
1020``` elixir
1121def deps do
@@ -15,7 +25,336 @@ def deps do
1525end
1626```
1727
18- Documentation can be generated with [ ExDoc] ( https://github.com/elixir-lang/ex_doc )
19- and published on [ HexDocs] ( https://hexdocs.pm ) . Once published, the docs can
20- be found at < https://hexdocs.pm/ecto_irs > .
28+ ## Quick Start
29+
30+ ### 1. Add Audit Columns to Your Database
31+
32+ In your migration:
33+
34+ ``` elixir
35+ defmodule MyApp .Repo .Migrations .CreatePosts do
36+ use Ecto .Migration
37+ import EctoIRS .Migration
38+
39+ def change do
40+ create table (:posts ) do
41+ add :title , :string
42+ add :content , :text
43+
44+ # Adds :inserted_by_id and :updated_by_id columns
45+ audits :users
46+
47+ timestamps ()
48+ end
49+ end
50+ end
51+ ```
52+
53+ ### 2. Add Audit Fields to Your Schema
54+
55+ In your schema:
56+
57+ ``` elixir
58+ defmodule MyApp .Post do
59+ use Ecto .Schema
60+ use EctoIRS .Schema
61+
62+ schema " posts" do
63+ field :title , :string
64+ field :content , :text
65+
66+ # Generates :inserted_by and :updated_by associations
67+ audits MyApp .User
68+
69+ timestamps ()
70+ end
71+ end
72+ ```
73+
74+ ### 3. Query with Audit Information
75+
76+ ``` elixir
77+ # Preload audit associations
78+ post = MyApp .Repo .get (MyApp .Post , 1 ) |> MyApp .Repo .preload ([:inserted_by , :updated_by ])
79+
80+ # Access audit information
81+ IO .puts " Created by: #{ post.inserted_by.name } "
82+ IO .puts " Last updated by: #{ post.updated_by.name } "
83+ ```
84+
85+ ## Schema Usage
86+
87+ ### Basic Usage
88+
89+ ``` elixir
90+ defmodule MyApp .Post do
91+ use Ecto .Schema
92+ use EctoIRS .Schema
93+
94+ schema " posts" do
95+ field :title , :string
96+ audits MyApp .User
97+ timestamps ()
98+ end
99+ end
100+ ```
101+
102+ ### Custom Field Names
103+
104+ ``` elixir
105+ defmodule MyApp .Post do
106+ use Ecto .Schema
107+ use EctoIRS .Schema
108+
109+ schema " posts" do
110+ field :title , :string
111+
112+ audits MyApp .User ,
113+ inserted_by: :created_by ,
114+ updated_by: :modified_by
115+ end
116+ end
117+ ```
118+
119+ ### Disable Specific Fields
120+
121+ ``` elixir
122+ defmodule MyApp .Post do
123+ use Ecto .Schema
124+ use EctoIRS .Schema
125+
126+ schema " posts" do
127+ field :title , :string
128+
129+ # Only track who created, not who updated
130+ audits MyApp .User , updated_by: false
131+ end
132+ end
133+ ```
134+
135+ ### Custom References
136+
137+ ``` elixir
138+ defmodule MyApp .Post do
139+ use Ecto .Schema
140+ use EctoIRS .Schema
141+
142+ schema " posts" do
143+ field :title , :string
144+
145+ audits MyApp .User , references: :user_id
146+ end
147+ end
148+ ```
149+
150+ ### Automatic Field Population
151+
152+ ``` elixir
153+ defmodule MyApp .Post do
154+ use Ecto .Schema
155+ use EctoIRS .Schema
156+
157+ schema " posts" do
158+ field :title , :string
159+
160+ audits MyApp .User , autogenerate: {MyApp .Context , :current_user_id , []}
161+ end
162+ end
163+ ```
164+
165+ ### Pre-configuration
166+
167+ ``` elixir
168+ defmodule MyApp .Post do
169+ use Ecto .Schema
170+ use EctoIRS .Schema
171+
172+ @audits_opts [autogenerate: {MyApp .Context , :current_user_id , []}]
173+
174+ schema " posts" do
175+ field :title , :string
176+ audits MyApp .User
177+ end
178+ end
179+ ```
180+
181+ ## Migration Usage
182+
183+ ### Basic Migration
184+
185+ ``` elixir
186+ defmodule MyApp .Repo .Migrations .CreatePosts do
187+ use Ecto .Migration
188+ import EctoIRS .Migration
189+
190+ def change do
191+ create table (:posts ) do
192+ add :title , :string
193+ audits :users
194+ timestamps ()
195+ end
196+ end
197+ end
198+ ```
199+
200+ ### Custom Column Names
201+
202+ ``` elixir
203+ defmodule MyApp .Repo .Migrations .CreatePosts do
204+ use Ecto .Migration
205+ import EctoIRS .Migration
206+
207+ def change do
208+ create table (:posts ) do
209+ add :title , :string
210+
211+ audits :users ,
212+ inserted_by: :created_by ,
213+ updated_by: :modified_by
214+
215+ timestamps ()
216+ end
217+ end
218+ end
219+ ```
220+
221+ ### Nullable Columns
222+
223+ ``` elixir
224+ defmodule MyApp .Repo .Migrations .CreatePosts do
225+ use Ecto .Migration
226+ import EctoIRS .Migration
227+
228+ def change do
229+ create table (:posts ) do
230+ add :title , :string
231+ audits :users , null: true
232+ timestamps ()
233+ end
234+ end
235+ end
236+ ```
237+
238+ ### Adding to Existing Tables
239+
240+ ``` elixir
241+ defmodule MyApp .Repo .Migrations .AddAuditsToExistingTable do
242+ use Ecto .Migration
243+ import EctoIRS .Migration
244+
245+ def change do
246+ alter table (:existing_posts ) do
247+ audits :users
248+ end
249+ end
250+ end
251+ ```
252+
253+ ### Custom Reference Options
254+
255+ ``` elixir
256+ defmodule MyApp .Repo .Migrations .CreatePosts do
257+ use Ecto .Migration
258+ import EctoIRS .Migration
259+
260+ def change do
261+ create table (:posts ) do
262+ add :title , :string
263+
264+ audits :users ,
265+ column: :user_id ,
266+ on_delete: :nilify_all ,
267+ on_update: :update_all
268+
269+ timestamps ()
270+ end
271+ end
272+ end
273+ ```
274+
275+ ## Configuration
276+
277+ ### Repository Configuration
278+
279+ Configure default audit options at the repository level:
280+
281+ ``` elixir
282+ config :my_app , MyApp .Repo ,
283+ migration_audits: [
284+ inserted_by: :created_by ,
285+ updated_by: :modified_by ,
286+ null: false
287+ ]
288+ ```
289+
290+ ### Schema Configuration Options
291+
292+ - ` inserted_by ` : The field name for insertion audit (default: ` :inserted_by ` )
293+ - ` updated_by ` : The field name for update audit (default: ` :updated_by ` )
294+ - ` references ` : The field on the referenced table (default: ` :id ` )
295+ - ` autogenerate ` : MFA tuple for automatic field population
296+
297+ ### Migration Configuration Options
298+
299+ - ` inserted_by ` : Column name prefix for insertion audit (default: ` :inserted_by ` )
300+ - ` updated_by ` : Column name prefix for update audit (default: ` :updated_by ` )
301+ - ` null ` : Whether columns accept null values (default: ` false ` )
302+
303+ ## Best Practices
304+
305+ ### 1. Add Indexes for Performance
306+
307+ ``` elixir
308+ create index (:posts , [:inserted_by_id ])
309+ create index (:posts , [:updated_by_id ])
310+ ```
311+
312+ ### 2. Use Consistent Naming
313+
314+ Stick to either the default names or establish a consistent naming convention across your application.
315+
316+ ### 3. Consider Nullable Columns
317+
318+ Decide whether audit fields should be required based on your application's security requirements.
319+
320+ ### 4. Preload Associations
321+
322+ Always preload audit associations when you need to access the audit information:
323+
324+ ``` elixir
325+ posts = MyApp .Repo .all (MyApp .Post ) |> MyApp .Repo .preload ([:inserted_by , :updated_by ])
326+ ```
327+
328+ ## Development
329+
330+ ### Running Tests
331+
332+ ``` bash
333+ mix test
334+ ```
335+
336+ ### Code Quality
337+
338+ ``` bash
339+ mix credo # Run static code analysis
340+ mix dialyzer # Run type checking
341+ ```
342+
343+ ### Documentation
344+
345+ ``` bash
346+ mix docs # Generate documentation
347+ ```
348+
349+ ## Contributing
350+
351+ 1 . Fork the repository
352+ 2 . Create your feature branch (` git checkout -b feature/amazing-feature ` )
353+ 3 . Commit your changes (` git commit -m 'Add some amazing feature' ` )
354+ 4 . Push to the branch (` git push origin feature/amazing-feature ` )
355+ 5 . Open a Pull Request
356+
357+ ## License
358+
359+ This project is licensed under the MIT License - see the [ LICENSE] ( LICENSE ) file for details.
21360
0 commit comments