forked from kreeti/rails-slides
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
900 lines (831 loc) · 33 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>reveal.js</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h2>Build Rails Application using MySQL, Devise, Bootstrap</h2>
<h5 style="text-transform:none">by Prosenjit saha</h5>
</section>
<section>
<h6>Before creating the rails app make sure you have installed the followings: </h6>
<ol>
<li>RVM</li>
<li>Rails</li>
<li>MYSQL Database</li>
</ol>
</section>
<section>
<h5>Introduction</h5>
<p>Ruby on Rails uses sqlite3 as its default database.</p>
<p>But it may not be sufficient for your application.</p>
<p>For scalability, centralization, and control we will use PostgreSQL or MySQL.</p>
</section>
<section>
<section>
<h4>Create New Rails Application</h4>
<p>Create a new Rails application in your home directory. Use the -d mysql option to set MySQL as the database, and be sure to substitute the highlighted word with your application name:</p>
<pre><code data-trim>
cd ~
rails new appname -d mysql
</code></pre>
<p>It will create the structure of your application and also install the gems and other dependencies</p>
</section>
<section>
<img data-src="./image/build-rails-app.png">
</section>
</section>
<section>
<p>Then move into the application's directory:</p>
<pre><code data-trim>
cd appname
</code></pre>
<p>The next step is to configure the application's database connection.</p>
</section>
<section>
<section>
<h4>Configure Database Connection</h4>
<p style="font-size: 25px;">If you followed the MySQL install instructions from this tutorial, you set a password for MySQL's root user. The MySQL root login will be used to create your application's test and development databases.</p>
<p style="font-size: 25px;">Open your application's database configuration file in your favorite text editor. We'll use emacs:</p>
<pre><code data-trim>
emacs config/database.yml
</code></pre>
<p style="font-size: 25px;">Under the default section, find the line that says "password:" and add the password to the end of it. It should look something like this (replace the highlighted part with your MySQL root password):</p>
<pre><code data-trim>password: mysql_root_password</code></pre>
<p style="font-size: 25px;">Save and exit.</p>
</section>
<section>
<img data-src="./image/database-yml.png">
</section>
</section>
<section>
<h4>Create Application Databases</h4>
<p>Create your application's development and test databases by using this rake command:</p>
<pre><code data-trim>rake db:create</code></pre>
<p>This will create two databases in your MySQL server. For example, if your application's name is "appname", it will create databases called "appname_development" and "appname_test".</p>
</section>
<section>
<section>
<h4>Test Configuration</h4>
<p>The easiest way to test that your application is able to use the MySQL database is to try to run it.</p>
<p>For example, to run the development environment (the default), use this command:</p>
<pre><code data-trim>rails server</code></pre>
<p>This will start your Rails application on your localhost on port 3000.</p>
</section>
<section>
<img data-src="./image/first-page.png">
</section>
</section>
<section>
<h2>Before going forward we will add our code to git repository</h2>
</section>
<section>
<h4>First-time system setup</h4>
<p>Before using Git, you should perform a couple of one-time setup steps. These are system setups, meaning you only have to do them once per computer:</p>
<pre><code data-trim>$ git config --global user.name "Your Name"
$ git config --global user.email [email protected]</code></pre>
</section>
<section>
<h4>First-time repository setup</h4>
<p>The first step is to navigate to the root directory of the app and initialize a new repository:</p>
<pre><code data-trim>$ git init
Initialized empty Git repository in /home/ubuntu/workspace/hello_app/.git/</code></pre>
<p>The next step is to add all the project files to the repository using git add -A:</p>
<pre><code data-trim>$ git add -A</code></pre>
<p>This command adds all the files in the current directory apart from those that match the patterns in a special file called .gitignore</p>
</section>
<section>
<section>
<p>The added files are initially placed in a staging area, which contains pending changes to our project. We can see which files are in the staging area using the status command</p>
<pre><code data-trim>
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached file..." to unstage)
new file: .gitignore
new file: Gemfile
new file: Gemfile.lock
new file: README.md
new file: Rakefile
.
.
.
</code></pre>
</section>
<section>
<p>To tell Git we want to keep the changes, we use the commit command:</p>
<pre><code data-trim>$ git commit -m "Initialize repository"
[master (root-commit) df0a62f] Initialize repository
.
.
. </code></pre>
<p>Now that we’ve put our project under version control with Git, it’s time to push our code up to Bitbucket</p>
</section>
<section>
<ol>
<li>Sign up for a Bitbucket account if you don’t already have one.</li>
<li>Copy your public key to your clipboard.
<pre><code data-trim>$ cat ~/.ssh/id_rsa.pub</code></pre>
</li>
<li>Add your public key to Bitbucket by clicking on the avatar image in the upper right and selecting “Manage account” and then “SSH keys”</li>
</ol>
</section>
<section><img data-src="./image/add_public_key.png"></section>
<section>
<p>Once you’ve added your public key, click on “Create” to create a new repository, </p>
<img data-src="./image/create_first_repository_bitbucket_4th_ed.png">
</section>
<section>
<pre><code data-trim>$ git remote add origin [email protected]:<username>/hello_app.git
$ git push -u origin --all</code></pre>
<p>The commands first tell Git that you want to add Bitbucket as the origin for your repository, and then push your repository up to the remote origin</p>
</section>
</section>
<section>
<h2>we will create our first controller and view</h2>
</section>
<section>
Before doing any changes we will create new git branch using the following command
<pre><code data-trim>$ git checkout -b branch_name
Switched to a new branch 'branch_name'
</code></pre>
</section>
<section>
<section>
We will create a controller name 'home' using the following command
<pre><code data-trim>$ rails g controller home
Running via Spring preloader in process 17742
create app/controllers/home_controller.rb
invoke erb
create app/views/home
invoke test_unit
create test/controllers/home_controller_test.rb
invoke helper
create app/helpers/home_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/home.coffee
invoke scss
create app/assets/stylesheets/home.scss
</code></pre>
</section>
<section>
Open home_controller.rb file in your editor
<pre><code data-trim>class HomeController < ApplicationController
end
</code></pre>
Add an action called index
<pre><code data-trim>class HomeController < ApplicationController
def index
end
end
</code></pre>
Now open the routes.rb file and 'home#index' as root_path
<pre><code data-trim>
Rails.application.routes.draw do
root 'home#index'
.
.
end
</code></pre>
</section>
<section>
Now go to the "app/view/home" folder and add index.html.erb file and add the following
<pre><code data-trim><h2>This is the home page</h2></code></pre>
Now run the rails server and open localhost:3000 in the browser, you will see
<img data-src="./image/home.png">
</section>
</section>
<section>
<section>
<h4>Commit the latest changes</h4>
To get the latest uncommited changes run the following command
<pre><code data-trim>$ git status
On branch home
Changes not staged for commit:
(use "git add file..." to update what will be committed)
(use "git checkout -- file..." to discard changes in working directory)
modified: config/routes.rb
Untracked files:
(use "git add file..." to include in what will be committed)
app/assets/javascripts/home.coffee
app/assets/stylesheets/home.scss
app/controllers/home_controller.rb
app/controllers/home_controller.rb~
app/helpers/home_helper.rb
app/views/home/
config/#routes.rb#
config/.#routes.rb
test/controllers/home_controller_test.rb
</code></pre>
</section>
<section>
<p>app/controllers/home_controller.rb~, config/#routes.rb# some unnecessary files are present in the list. So we will not commit those file.</p>
<p>To ignore these file open .gitignore file and add the following</p>
<pre><code data-trim>*~
*#
</code></pre>
Rest of the untracked files we will add to git by running the following command
<pre><code data-trim>$ git add .</code></pre>
Or we can add files by typing the filename with path, like
<pre><code data-trim>$ git add app/helpers/home_helper.rb app/views/home/</code></pre>
</section>
<section>
Now if you do git status you can see these
<pre><code data-trim> $ git status
On branch home
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: .gitignore
new file: app/assets/javascripts/home.coffee
new file: app/assets/stylesheets/home.scss
new file: app/controllers/home_controller.rb
new file: app/helpers/home_helper.rb
new file: app/views/home/index.html.erb
modified: config/routes.rb
new file: test/controllers/home_controller_test.rb</code></pre>
<p>Now we will commit these changes</p>
<pre><code data-trim>git commit -m "add home controller" -a</code></pre>
</section>
<section>
Merge these branch into master
<pre><code data-trim>$ git checkout master
$ git merge home
Updating e6ae8cf..7bf82bd
Fast-forward
.gitignore | 3 +++
app/assets/javascripts/home.coffee | 3 +++
app/assets/stylesheets/home.scss | 3 +++
app/controllers/home_controller.rb | 4 ++++
app/helpers/home_helper.rb | 2 ++
app/views/home/index.html.erb | 1 +
config/routes.rb | 6 +-----
test/controllers/home_controller_test.rb | 7 +++++++
8 files changed, 24 insertions(+), 5 deletions(-)
create mode 100644 app/assets/javascripts/home.coffee
create mode 100644 app/assets/stylesheets/home.scss
create mode 100644 app/controllers/home_controller.rb
create mode 100644 app/helpers/home_helper.rb
create mode 100644 app/views/home/index.html.erb
create mode 100644 test/controllers/home_controller_test.rb
</code></pre>
</section>
</section>
<section>
<h2>Add bootstrap to our project</h2>
</section>
<section>
<section>
<p>Create a new branch from master</p>
<pre><code data-trim>$ git checkout -b add_bootstrap</code></pre>
<p>Open Gemfile, add "gem 'bootstrap-sass'" to list and do bundle</p>
<p>Now go to app/assets/stylesheets folder, change filename application.css to application.scss, remove all the content and add the following</p>
<pre><code data-trim>@import "bootstrap-sprockets";
@import "bootstrap";
</code></pre>
<p>Open app/assets/javascripts/application.js file and add the following</p>
<pre><code data-trim>//= require bootstrap-sprockets</code></pre>
And remove
<pre><code data-trim>//= require turbolinks</code></pre>
</section>
<section>
Open app/views/layout/application.html.erb file and replace the content
<pre><code data-trim><!DOCTYPE html>
<html>
<head>
<title>TestApp</title>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
</head>
<body>
<%= render "layouts/navbar" %>
<div class="container">
<%= yield %>
<%= javascript_tag do %>
<%= yield :javascript %>
<% end %>
<hr>
<footer>
<p>© 2016 Company, Inc.</p>
</footer>
</div>
<div class="modal-container"></div>
</body>
</html>
</code></pre>
</section>
<section>
In the above code we have added a partial
<pre><code data-trim><%= render "layouts/navbar" %></code></pre>
This contains the navigation bar for your site. But there is no file as such. So add '_navbar.html.erb' to app/views/layout folder and add the following code
<pre><code data-trim>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<%= link_to "Home", root_path, class: "navbar-brand" %>
</div>
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</nav>
</code></pre>
</section>
<section>
Now if you open the browser you can see these
<img data-src="./image/bootstrap-home.png">
</section>
<section>
Agian commit your changes and pushed to github
<img data-src="./image/add-boot-to-git.png">
</section>
</section>
<section>
<h2>Add devise to our application</h2>
</section>
<section>
<p>Devise is a flexible authentication solution for Rails application</p>
<p>For documentation you can go through <a href="https://github.com/plataformatec/devise">https://github.com/plataformatec/devise</a></p>
</section>
<section>
<section>
You can add it to your Gemfile with:
<pre><code data-trim>gem 'devise'</code></pre>
<p>Run the bundle command to install it.</p>
Next, you need to run the generator:
<pre><code data-trim>$ rails generate devise:install</code></pre>
</section>
<section>
<img data-src="./image/devise.png">
</section>
<section>
<p>Add Devise to any of your models using the generator.</p>
<pre><code data-trim>$ rails g devise user
Running via Spring preloader in process 19374
invoke active_record
create db/migrate/20160824093232_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
</code></pre>
<p>The above has created a model and migration for user and also modify the routes file</p>
</section>
<section>
<img data-src="./image/user-migration.png">
</section>
<section>
<img data-src="./image/user-model.png">
</section>
<section>
<img data-src="./image/routes.png">
</section>
<section>
Then run rake db:migrate
<pre><code data-trim>$ rake db:migrate
== 20160824093232 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.3213s
-- add_index(:users, :email, {:unique=>true})
-> 0.3117s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.2766s
== 20160824093232 DeviseCreateUsers: migrated (0.9101s) =======================
</code></pre>
</section>
<section>
Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_action
<pre><code data-trim>before_action :authenticate_user!</code></pre>
To verify if a user is signed in, use the following helper:
<pre><code data-trim>user_signed_in?</code></pre>
For the current signed-in user, this helper is available:
<pre><code data-trim>current_user</code></pre>
</section>
</section>
<section>
<h2>Now we are ready to use devise without doing any further change</h2>
</section>
<section>
<section>
<img data-src="./image/signin.png">
</section>
<section>
<img data-src="./image/signup.png">
</section>
</section>
<section>
Commit all the changes and merge to master
</section>
<section>
<h2>Add users controller and modify the navigation bar</h2>
</section>
<section>
<section>
<p>Create a new branch from master first</p>
<p>For users we will need index and show action</p>
<pre><code data-trim>
$ rails g controller users index show
Running via Spring preloader in process 19759
create app/controllers/users_controller.rb
route get 'users/show'
route get 'users/index'
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/show.html.erb
invoke test_unit
create test/controllers/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/users.coffee
invoke scss
create app/assets/stylesheets/users.scss
</code></pre>
Above will create users controller with two action and the corresponding view
</section>
<section>
<img data-src="./image/users.png">
</section>
<section>
Replace the controller code with following
<pre><code data-trim>
class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end
</code></pre>
</section>
<section>
Now open the app/views/users/index.html.erb and replace content with following
<pre><code data-trim>
<div class="container">
<div class="row">
<h3>Users</h3>
<div class="column">
<table class="table">
<tbody>
<% @users.each do |user| %>
<tr>
<td><%= link_to user.email, user %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</code></pre>
</section>
<section>
Now open the app/views/users/show.html.erb and replace content with following
<pre><code data-trim>
<div class="container">
<div class="row border-bottom">
<h4 class="pull-left"><%= @user.email %></h4>
</div>
</div></code></pre>
</section>
<section>
Update the routes file
<pre><code data-trim>
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:index, :show]
root 'home#index'
end
</code></pre>
</section>
</section>
<section>
Update the content of navbar.html.erb
<pre><code data-trim>
<ul class="nav navbar-nav navbar-right">
<% if user_signed_in? %>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<%= current_user.email %> <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><%= link_to "Profile", user_path(current_user) %></li>
<li role="separator" class="divider"></li>
<li><%= link_to "Log out", destroy_user_session_path, method: "Delete" %></li>
</ul>
</li>
<% else %>
<li><%= link_to "Log in", "users/sign_in" %></li>
<% end %>
</ul>
</code></pre>
</section>
<section>
<section>
<img data-src="./image/users-index.png">
</section>
<section>
<img data-src="./image/user-show.png">
</section>
</section>
<section>
Commit your changes, merge with master and push to git repository
</section>
<section>
<h2>Create User's post</h2>
</section>
<section>
<p>First we will add model for post. Post model contains title, content, user_id as attributes</p>
<p>To create post model run the command. It will create table called posts</p>
<pre><code data-trim>$ rails g model post user_id:integer title:string content:text
Running via Spring preloader in process 20354
invoke active_record
create db/migrate/20160824105601_create_posts.rb
create app/models/post.rb
invoke test_unit
create test/models/post_test.rb
create test/fixtures/posts.yml</code></pre>
OR
<pre><code data-trim>$ rails g model post</code></pre>
Then open the migration file and add the columns.
</section>
<section>
Add constraints to migration file
<pre><code data-trim>
create_table :posts do |t|
t.integer :user_id, null: false
t.string :title, null: false
t.text :content, null: false
t.timestamps null: false
end
</code></pre>
Then finally run the command
<pre><code data-trim>$ rake db:migrate
== 20160824105601 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.3062s
== 20160824105601 CreatePosts: migrated (0.3064s) =============================</code></pre>
</section>
<section>
Forgot to add foreign key to posts table.
</section>
<section>
Don't worry :P
</section>
<section>
<section>
we can add it to existing migration or we can add a new migration for this
</section>
<section>
If the last migration is recently created and it's not committed or pushed yet we can rollback the migration and modify and re-run the migration
</section>
<section>
To rollback the last migration rub the command
<pre><code data-trim>rake db:rollback
== 20160824105601 CreatePosts: reverting ======================================
-- drop_table(:posts)
-> 0.1500s
== 20160824105601 CreatePosts: reverted (0.3737s) =============================</code></pre>
Add the following to the migration
<pre><code data-trim>add_foreign_key :posts, :users</code></pre>
Re-run the command
<pre><code data-trim>rake db:migrate
== 20160824105601 CreatePosts: migrating ======================================
-- create_table(:posts)
-> 0.2946s
-- add_foreign_key(:posts, :users)
-> 0.6877s
== 20160824105601 CreatePosts: migrated (0.9826s) =============================
</code></pre>
</section>
<section>
Or to create a new migration run the command
<pre><code data-trim>rails g migration add_foreign_key_to_posts
Running via Spring preloader in process 20541
invoke active_record
create db/migrate/20160824111210_add_foreign_key_to_posts.rb
</code></pre>
In the new migration file just add the following line and run the migration
<pre><code data-trim>add_foreign_key :posts, :users</code></pre>
<pre><code data-trim>rake db:migrate
== 20160824111210 AddForeignKeyToPosts: migrating =============================
== 20160824111210 AddForeignKeyToPosts: migrated (0.0000s) ====================
</code></pre>
</section>
</section>
<section>
<section>
In this section we will add association and validation for post
</section>
<section>
<p>If we notice the posts table, we will see user_id is present. i.e, post belongs to user.</p>
<p>So we will add belongs_to association in post model.</p>
<p>Open app/models/post.rb and add following.</p>
<pre><code data-trim>belongs_to :user</code></pre>
<p>We will have to add the reverse association too.</p>
<p>For this open app/model/user.rb and add following.</p>
<pre><code data-trim>has_many :posts</code></pre>
</section>
<section>
We are done with association. Now we have to add model validation
</section>
<section>
<p>Open app/models/post.rb and add following.</p>
<pre><code data-trim>validates :user_id, :title, :content, presence: true</code></pre>
<p>It will check presence for the above attributes</p>
</section>
</section>
<section>
<section>
We will add controller for posts. We will add four actions(index, new, create, show)
</section>
<section>
Run the command to create the posts controller
<pre><code data-trim>rails g controller posts
Running via Spring preloader in process 20671
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
invoke test_unit
create test/controllers/posts_controller_test.rb
invoke helper
create app/helpers/posts_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/posts.coffee
invoke scss
create app/assets/stylesheets/posts.scss</code></pre>
open the routes file and add the following line
<pre><code data-trim>resources :posts, only: [:index, :show, :new, :create]</code></pre>
</section>
</section>
<section>
<section>
<p>Now first we will add controller logic and view for new action.</p>
<p>First open the controller code and add the following lines.</p>
<pre><code data-trim> before_action :authenticate_user!
def new
@post = current_user.posts.build
end
</code></pre>
</section>
<section>
<p>Create new.html.erb file in app/views/posts folder and add the following line</p>
<pre><code data-trim>
<%= form_for @post, method: "POST", html: { class: "form-horizontal" } do |f| %>
<div class="form-group">
<%= f.label :title, class: "col-sm-3 control-label" %>
<div class="col-sm-8">
<%= f.text_field :title, class: "form-control", required: true %>
</div>
</div>
<div class="form-group">
<%= f.label :content, class: "col-sm-3 control-label" %>
<div class="col-sm-8">
<%= f.text_area :content, class: "form-control", required: true %>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<%= f.submit "Save", class: "btn btn-default" %>
</div>
</div>
<% end %>
</code></pre>
</section>
<section>
Now if you open the localhost:3000/posts/new you will see this
<img data-src="./image/new-post.png">
</section>
</section>
<section>
<section>
Now we will add create action to handle the post creation
</section>
<section>
Open posts controller and add the following line
<pre><code data-trim>
def create
post = current_user.posts.build(post_params)
if post.save
redirect_to posts_path, notice: "Post has been successfully created"
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :content)
end
</code></pre>
</section>
<section>
if you check your log you will get the following when you submit the form
<pre><code data-trim>
Started POST "/posts" for 127.0.0.1 at 2016-08-24 17:22:50 +0530
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Q26W6t0dESfOznim0e8aQEu4dpehBekEVveynGV2HzSVi5z1m2QZx6rXjvvpsTjFNAD35hC+wComCdMfKPwUGQ==", "post"=>{"title"=>"My first Post", "content"=>"Sample post created for rails tuttorial"}, "commit"=>"Save"}
User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `posts` (`title`, `content`, `user_id`, `created_at`, `updated_at`) VALUES ('My first Post', 'Sample post created for rails tuttorial', 2, '2016-08-24 11:52:50', '2016-08-24 11:52:50')
(39.9ms) COMMIT
Redirected to http://localhost:3000/posts
Completed 302 Found in 92ms (ActiveRecord: 45.5ms)
</code></pre>
</section>
</section>
<section>
<section>
<p>Now we will add the index action for post. Before adding index action we will add 'will_paginate' gem to our apllication</p>
<p>For will_paginate please go through the <a href="https://github.com/mislav/will_paginate">https://github.com/mislav/will_paginate</a></p>
</section>
<section>
Add the following code to posts controller
<pre><code data-trim>
def index
@posts = Post.paginate(:page => params[:page])
end </code></pre>
Create index.html.erb file and add the followings
<pre style="font-size:25px;"><code data-trim>
<div class="container">
<div class="row">
<h3 class="pull-left">Posts</h3>
<%= link_to "Add new post", new_post_path, class: "btn btn-primary pull-right" %>
<div class="column">
<table class="table">
<thead>
<tr>
<th>Author</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= link_to post.user.email, post.user %></td>
<td><%= link_to post.title, post %></td>
</tr>
<% end %>
</tbody>
</table
</div>
</div>
</div>
</code></pre>
</section>
<section>
Now if you go to http://localhost:3000/posts you will see
<img data-src="./image/posts-index.png">
</section>
</section>
<section>
Do you have any question?
</section>
<section>
Thanks!!!
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
history: true,
// More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>