-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrails_useful.txt
958 lines (646 loc) · 32.2 KB
/
rails_useful.txt
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
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
per installare sublime text in seguenza scrivere le seguenti stringhe
1a stringa) wget http://c758482.r82.cf2.rackcdn.com/Sublime\ Text\ 2.0.2\ x64.tar.bz2
2a stringa) tar vxjf Sublime\ Text\ 2.0.2\ x64.tar.bz2
3a stringa) sudo mv Sublime\ Text\ 2 /opt/
4a stringa) sudo ln -s /opt/Sublime\ Text\ 2/sublime_text /usr/bin/sublime
per installare rvm rails e ruby seguire i seguenti steps:
step 0) sudo apt-get install curl
step 1) copia incolla sul terminale la seguente stringa:
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
step 2) \curl -sSL https://get.rvm.io | bash -s stable --rails
step 3) echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"' >> .bashrc
step 4) per evitare che l'installazione di una gem sia troppo lenta scrivere:
gem: --no-ri --no-rdoc
step 5) reboot system
0) per controllare se ImageMagick è installato digitare: identify -version
1)per installare ruby tramite rvm: rvm install 2.2.0 (che sarebbe la versione di ruby che si vuole installare)
2)per controllare quale versione stiamo usando di ruby scrivere: ruby -v
3)per installare la documentazione relativa al ruby che stiamo usando, una volta usato il 5) digitare: rvm docs generate all
4)per vedere quale ruby versions su rvm ho installato digitare: rvm list
5)per settare di default una versione di ruby su rvm digitare: rvm --default 2.1.3 per esempio
6)per cancellare una versione di ruby con rispettivo gemset digitare: rvm remove ruby-2.0.0(dove ruby-2.0.0 è appunto la versione di ruby che si vuole rimuovere)
7)per controllare quale versione di rails stiamo usando digitare: rails -v
8)per installare una gem di default su rvm su una speciale versione di ruby usare prima il 4) e 5) e poi digitare: sudo gem install nomeDellaGemCheSiVuoleInstallare
9) se si vuole creare un sito con il cms refineryCms selezionare ruby-2.2.0 dall'rvm e poi digitare: rails new my_new_application -m http://refinerycms.com/t/edge
You can create scaffolding using:
rails generate scaffold MyFoo (or similar),
Or
rails generate scaffold MyFoo title:string notes:text
and you can destroy/undo it using
rails destroy scaffold MyFoo
f
You can create model using:
rails generate model MyFoo (or similar),
and you can destroy/undo it using
rails destroy model MyFoo
If you want to UNDO the last migration:
rake db:rollback
If you need to undo several migrations you can provide a STEP parameter:
rake db:rollback STEP=3
if you want to reset the db
rake db:reset task will drop the database and set it up again. This is functionally equivalent to rake db:drop db:setup.
------------------------------------------------------------------------------------------------------------------------------
GITHUB
git add .
git commit -am "inserisci una descrizione "
git status
per traferire il git locale online su github.com e ad esempio da directory del progetto che abbiamo sviluppato si chiama wiki scriveremo:
git remote add origin https://github.com/corradt/wiki.git
git push -u origin master
---------------------------------------------------------------------------------------------------------------------
HOW TO ANNULL A SCAFFOLDING
if you did
rails g scaffold Store
you can annull it using the following command
rails destroy scaffold MyFoo
--------------------------------------------------------------------------------------------------------------------------------
ACTIVE RECORD - MIGRATION
Model / Class Table / Schema
Article articles
LineItem line_items
Deer deers
Mouse mice
Person people
quando usiamo
rails g scaffold Product title:string description:text
lui automaticamente ci creera' un Model/Class con il nome maiuscolo Product e allo stesso tempo ci creera' la tabella con il nome minuscolo products
If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types then a migration containing the appropriate add_column and remove_column statements will be created. Per esempio:
se vogliamo aggiungere una chiave esterna user_id come attributo/colonna alla classe/tabella contemporaneamente alla classe e alla tabella dovremmo scrivere
rails generate migration AddUserIdToProducts user_id:integer
Similarly, you can generate a migration to remove a column from the command line:
rails generate migration RemoveUserIdFromProducts user_id:integer
e' ovvio che l'attributo/colonna non necessariamente deve essere di tipo integer
ovviamente si potrebbe aggiungere piu' attributi o colonne in una volta sola per esempio:
rails generate migration AddDetailsToProducts part_number:string price:decimal
If the migration name is of the form "CreateXXX" and is followed by a list of column names and types then a migration creating the table XXX with the columns listed will be generated. For example:
rails generate migration CreateProducts name:string part_number:string
----------------------------------------------------------------------------------------------------------------
PER INSERIRE IMMAGINI,VIDEO,FONTS ETC.. IN CARTELLE DEDICATE PROPRIO A QUESTO
andare sulla cartella config e nel file application.rb inserire la seguente stringa
config.assets.paths << Rails.root.join("app", "assets", "fonts")
---------------------------------------------------------------------------------------------------------
OPERATORE TERNARIO
label= length ==1 ? " argument" : " arguments"
la sopra elencata riga dice se length è uguale a 1 assegna la stringa " argument" alla variabile label altrimenti gli assegna la stringa " arguments"
un'altro esempio definendo una funzione
def pluralize(qta)
label= qta==1 ? sprintf("%d", qta) + " prodotto" : sprintf("%d", qta) + " prodotti"
label
end
puts pluralize(4) -----> l'output sara' 4 prodotti
puts pluralize(1) -----> l'output sara' 1 prodotto
-------------------------------------------------------------------------------------------------------------------------------------------------------
COMMENTO MULTIRIGA
=begin
this is a multiple line comment
=end
ma il migliore metodo e' quello che segue
In application_helper.rb, aggiungere un metodo cosi':
def comment
end
poi nella file dove si vuole commentare scrivere cosi':
<% comment do %> bla bla bla...<% comment end %>
------------------------------------------------------------------------------------------------------------------------------------------------
UNTIL simile al ciclo while
age=1 //variabile
puts age +=1 until age > 28 // stampera' una seq di num a partire dal num 2 fino ad arrivare a 29
// age += 1 significa age=age+1
-------------------------------------------------------------------------------------------------------------------------------------------------
BLOCK
un blocco può essere espresso o attraverso le clausole do - end oppure attraverso le parentesi graffe {}. Praticamente |element| serve a memorizzare il
dato appena estratto ad ogni iterazione del costrutto each.
pacific=["washington","Oregon","California"]
pacific.each do |element|
puts element
end
lo stesso risultato di sopra si ottiene come segue:
pacific.each {|element| puts element}
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Classe
anzicche' usare attr_reader, attr_writer che servono a settare rispettivamente metodo getter e setter usiamo attr_accessor che lo stesso lavoro di entrambi.
Di seguito diciamo che vogliamo i metodi getter and setter sia per name che per surname
class Persona
@@countPerson=0 #variabile di classe il cui valore viene condiviso con tutte le variabili di istanza,
#in questo caso mi serve per contare quante persone sono state create
attr_accessor :name,:surname
def initialize()
@@countPerson +=1
end
def totale
@@countPerson.to_i
end
def fullName
@name.to_s+" "[email protected]_s #converto la variabile di istanza name e surname in stringa
end
end
p1=Persona.new()
p2=Persona.new()
#p1.hello_matz
p1.name="Corrado" #qui viene utilizzato il metodo setter
p1.surname="Tuccitto" #qui viene utilizzato il metodo setter
p2.name="Giuseppe" #qui viene utilizzato il metodo setter
p2.surname="Pelligra" #qui viene utilizzato il metodo setter
persone=[p1,p2]
persone.each {|element| puts element.name+" "+element.surname} # qui vengono usati i metodi getter
----------------------------------------------------------------------------------------------------------------------------------------------
EREDITA' si ottiene postponendo < alla classe che andra' a ereditare tutte le caratteristiche attributi e metodi della classe madre.
quando si eredita se la classe da cui si eredita non si trova nel presente file usare require e posizionarla come prima istruzione.
class Studente < Persona
end
s1=Studente.new()
s2=Studente.new()
#p1.hello_matz
s1.name="Corrado"
s1.surname="Tuccitto"
s2.name="Giuseppe"
s2.surname="Pelligra"
studenti=[s1,s2]
studenti.each {|element| puts element.name+" "+element.surname}
puts s2.totale # 2
puts s1.fullName # Corrado Tuccitto
-------------------------------------------------------------------------------------------------------------------------------------------
COND ITIONAL COSTRUTTI
if x == y then puts "x equals y" end
if x != y: puts "x is not equal to y" end
if x > y:
then puts "x equals y"
end
if x !== y then puts "x does not equal y" end
if !x>y
put "x is not greater than y"
end
ruby="nifty"
programming="fun"
x=2
if ruby == "nifty" && programming =="fun" || x<=2
puts "keep programming"
end
-----------------------------------------------------------------------------------------------------------------------------------------
UNLESS e' la forma negata dell'if
unless lang=="de"
dog="dog"
else
dog="hund"
end
------------------------------------------------------------------------------------------------------------------------------------
CASE di seguito vedremo come alla cariabile dog verra' assegnata la parola chien
lang ="fr"
dog=case lang
when "en":"dog"
when "es":"perro"
when "fr":"chien"
when "de":"Hund"
else "dog"
end
-------------------------------------------------------------------------------------------------------------------------------
scale =8
case scale
when 0: puts "lowest"
when 1..3:puts "medium-lo"
when 4..5:puts "medium"
when 6..7:puts "medium-high"
when 8..9:puts "high"
when 10:puts "highest"
else puts "off scale"
end
#la risposta stampata sara' high perche' scale e' incluso nel range di 8 a 9
--------------------------------------------------------------------------------------------------------------------------------------------
MODULI E MIXINS
i moduli sono come le classi ma non possono essere istanziati come una classe. Una classe può includere un modulo, così quando la classe viene istanziata, essa
possederà i metodi inclusi nel modulo. I metodi inclusi nel modulo una volta importato diventeranno metodi di istanza della classe che include il modulo.
Mentre si possono includere più moduli, questo e' simile all'ereditarietà multipla, l'ereditarietà della classe e singola cioè non si può ereditare da più classi differenti.
il nome di un modulo inizia sempre con una lettera Maiuscola
module Dice
def roll
r_1=rand(6); r_2=rand(6)
end
end
class Game
include Dice
end
g=Game.new
g.roll
se il modulo Dice e la classe Game fossero in separati file,allora si richiede il file contenente il modulo, questa richiesta la si posizione prima della chiamata
al modulo Dice
----------------------------------------------------------------------------------------------------------------------------------------------------------
PER INSTALLARE POSTGREESQL
sudo apt-get update
sudo apt-get install postgresql-common
sudo apt-get install postgresql-9.3 libpq-dev
sudo -u postgres createuser nomeDesiderato -s nome che ho scelto per il db eagle lo stesso per la password
sudo -u postgres psql
\password passwordDesiderata
\q serve per uscire
spree: [email protected]
nscnfm
-----------------------------------------------------------------------------------------------------------------------------
REGULAR EXPRESSIONS
se io ho la stringa seguente:
stringa="il server è stato aggiornato il 02/25/2015 del mattino"
e per esempio voglio estrapolare la data da questa stringa, procedo anzitutto creandomi l'espressione regolare che mi identifica la data
(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{4})
e poi tra le / / metto l'espressione regolare che identifica la data
/(?<month>\d{1,2})\/(?<day>\d{1,2})\/(?<year>\d{4})/.match(stringa)
------------------------------------------------------------------------------------------
HASH
per creare un hash con un elemento:
horses = {"primo" => {age:23,categoria:34}}
per aggiungere un secondo elemento
horses["secondo"] = {age:83,categoria:64}
--------------------------------------------------------------------------------
old_hash = {:a=>"A",:b=>"B",:c=>"C",:d=>"D",:e=>"E",:f=>"F"}
only_keys = [:a,:c,:f]
new_hash = Hash[*old_hash.find_all{|k,v| only_keys.member?(k)}.flatten]
il risultato sara'un nuovo hash che e' un sottoinsieme ristretto alle chiavi dichirato nell'array only_keys:
# => {:a=>“A”, :c=>“C”, :f=>“F”}
la stessa cosa possiamo fare dichiarando un array di valori only_vals
only_vals = ["A","D","G"]
new_hash = Hash[*old_hash.find_all{|k,v| only_vals.member?(v)}.flatten]
il risultato sara'un nuovo hash che e' un sottoinsieme ristretto ai valori dichirati nell'array only_vals:
# => {:a=>“A”, :d=>“D”}
---------------------------------------------------------------------------------------------
CONCATENAZIONE
per me il miglior metodo di concatenazione se per esempio si vuole concatenare quanto segue
request.fullpath == "/contacts/"+current_user.id
anzicche' usare il segno +
ecco come interpolare request.fullpath == "/contacts/#{current_user.id}"
UN ALTRO ESEMPIO
"http://www.caat.it/it/listino/"+(Time.now).strftime("%Y-%m-%d")
anzicche' usare il segno +
ecco come interpolare "http://www.caat.it/it/listino/#{(Time.now).strftime("%Y-%m-%d")}"
UN ALTRO ESEMPIO per concatenare un intero con una stringa e ritorno a capo
data un intero i=0
print "numero #{i} \n"
--------------------------------------------------------------------------------------------------------------------------------
HELPERS
gli helpers sono utili per avere una maggiore pulizia di codice
per esempio io l'ho utilizzato perchè necessitavo controllare se esisteva una pagina di prezzi aggiornata, se questa non esisteva la funzione doveva cercare l'ultima pag di prezzi più aggiornata quindi negli helper relativa alla view ho posizionato le varie librerie che andrò a utilizzare in questa funzione e poi ho definito la funzione che mi fa il check della pag e nella view ho richimato semplicemente la funzione e ho associato questa funzione una variabile di seguito ecco il codice:
#pages_helper.rb#
require "open-uri"
require 'rubygems'
require 'nokogiri'
def exists_prezzi_page
if Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now).strftime("%Y-%m-%d")}"))
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now).strftime("%Y-%m-%d")}"))
elsif Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-1.days).strftime("%Y-%m-%d")}"))
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-1.days).strftime("%Y-%m-%d")}"))
elsif Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-2.days).strftime("%Y-%m-%d")}"))
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-2.days).strftime("%Y-%m-%d")}"))
elsif Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-3.days).strftime("%Y-%m-%d")}"))
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-3.days).strftime("%Y-%m-%d")}"))
elsif Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-4.days).strftime("%Y-%m-%d")}"))
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-4.days).strftime("%Y-%m-%d")}"))
else
return Nokogiri::HTML(open("http://www.caat.it/it/listino/#{(Time.now-5.days).strftime("%Y-%m-%d")}"))
end
end
#prezzi_mercato_torino.html.erb#
<% doc=exists_prezzi_page %>
<% @righe=doc.css(".views-table") %>
<% @righe.each do |intestazione| %>
<table class="table table-condensed">
<tr>
<th><%= intestazione.at_css(".views-field-field-specie").text %></th>
<th><%= intestazione.at_css(".views-field-field-varieta").text %></th>
.....
IMPORTANTE!!! NON OCCORRE chiudere la funzione <% doc=exists_prezzi_page %> con <% end %> alla fine
--------------------------------------------------------------------------------------------------------------
UN'ALTRO ESEMPIO per rendere maiuscolo il contenuto di una variabile mettere nell'helper :
def capitalize(string)
string.capitalize
end
mentre nella view richiamare la funzione come segue:
<%= capitalize @user.name %>
-------------------------------------------------------------------------------------------------------------------------------------
FUNZIONI RICORSIVE
def step(i)
if i<5
puts "step #{i} "
i +=1
step(i)
end
end
chiamando la funzione step(0)
avremo come output
step 0
step 1
step 2
step 3
step 4
------------------------------------------------------------------------------------------------
DATE & TIME
(Time.now).strftime("%Y-%m-%d") significa dammi solo la data di oggi senza l'orario converti il risultato di Time.now in una stringa formattata
nel seguente formato 2015-03-23 per esempio
se volessi la data di ieri senza l'orario (Time.now-1.days).strftime("%Y-%m-%d")
se volessi la data di l'altro ieri senza l'orario (Time.now-2.days).strftime("%Y-%m-%d")
se invece volessi conoscere solo l'ora e non la data nel formato 18:01:30 scrivere
Time.now.strftime("%H:%M:%S")
Da notare: Sia per la Data sia per l'ora i due punti possono essere sostituiti con un simbolo a proprio piacimento
---------------------------------------------------------------------------------------------------------------------------
PROBLEMI RISOLTI E CONSIGLI PER L'USO
FOUNDATION
Attenzione!!! installazione di foundation implichera' la perdita dei dati nelle varie view quindi fare backup
Se si vuole utilizzare foundation usare il seguente
gem 'foundation-rails', '5.4.3.1' ATTENZIONE:!!! ALTRE VERS. NON FUNZIONANO
poi dal terminale scrivere:
rails g foundation:install
PROBLEMA RISCONTRATO E RISOLTI:
il logout non funziona questo perchè con Devise
aprire il file config/initializers/devise.rb
# The default HTTP method used to sign out a resource. Default is :delete. Noi dobbiamo passare da :delete a :get
config.sign_out_via = :delete la presente riga CAMBIARLa con la stringa seguente
config.sign_out_via = :get
HIGH_VOLTAGE
installare la seguente
gem 'high_voltage', '~> 2.2.1'
poi sotto la directory views, creare una directory di nome pages
app/views/pages
all'interno di essa creare una pagina statica del tipo home.html.erb
poi all'interno del percorso config/initializers/
creare un file high_voltage.rb all'interno di esso inserire le seguenti stringhe rinchiuse tra #
###################################
HighVoltage.configure do |config|
config.home_page = 'home' ATTENZIONE: QUI "home" e' il nome della pagina che abbiamo creato noi nella directory views
end
##################################
SSH
per copiare un file da A a B mentre se loggato in A
scp -P 3022 -r ./helloapp [email protected]:/
scp sta per secure copy
-P sta per indicare la porta
3022 e' la porta
-r sta per recursive quindi server per copiare ricorsivamente tutti i file all'interno della directory
./helloapp indicar il percorso della directory che si intende copiare in questo caso e' helloapp
root spcecifica che si vuole accedere come utente root
@ collegati a
www.rubyonrails-apps.com: rappresenta l'indirizzo dove si vuole copiare
/ stiamo specicando come directory di destinazione / directory radice
----------------------------------------------------------------------------------------------------------------------
PER DISPORRE PIU' OGGETTI PER RIGA
se si cercando di estrarre i prodotti di una tabella e vogliamo disporli 3 per ogni riga, allora creiamo un partial di nome _product.html.erb
ed in questo partial mettiamo il seguente codice
<% @products.in_groups_of(3, false).each do |group| %>
<div class='row'>
<% group.each do |product| %>
<div class='col-md-4'>
<div class="thumbnail">
<%=image_tag(product.image_url, class: "img-responsive") %>
<div class="caption">
<h3><%= product.title %></h3><p> <%= sanitize(product.description) %></p>
<p><a href=<%=line_items_path(product_id: product) %> class="btn btn-primary" role="button">Add to cart</a><%= number_to_currency(product.price) %></p></div>
</div>
</div>
<% end %>
</div>
<% end %>
-----------------------------------------------------------------------------------------------------------------------
PER BOOTSTRAP
gem 'twitter-bootstrap-rails', '~> 3.2.0'
da terminale digitare
rails generate bootstrap:install static
DOPO BOOTSTRAP INSTALLARE SIMPLE FORM
gem 'simple_form', '~> 3.1.0'
rails generate simple_form:install --boostrap
DOPO SIMPLE FORM INSTALLARE DEVISE
gem 'devise'
rails generate devise:install
rails generate devise user
rails generate devise:views
Attenzione!!! aggiungere la seguente linea al file development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
-----------------------------------------------------------------------------------
OGGETTO & SIMBOLO
con la seguente scrittura :x stiamo rappresentando un oggetto; i campi di una tabella,l'email,la password,l'url sono oggetti
con la seguente scrittura x: stiamo rappresentando un simbolo o per meglio dire stiamo specificando/indicando una caratteristica o per indicare un oggetto in memoria per esempio nel caso di un hash={key: "stringa1",key2:"stringa2"}
required: true, created_at: datetime, updated_at: datetime, autofocus: true, label: false, placeholder: "Email",input_html: {class: "form-control"}
required,autofocus,label,placeholder,input_html:,class: tutti questi INDICANO una caratteristica
come capire se occorre usare il simbolo o un oggetto?
utilizziamo il simbolo se vogliamo specificare o indicare un percorso o una caratteristica. Ci serviamo dei simboli per trasformare, modificare, creare, cancellare, aggiornare gli oggetti
method: :delete in questo caso stiamo utilizzando un simbolo e un oggetto, method: e' il simbolo mentre :delete e' l'oggetto
-------------------------------------------------------------------------
FIND
attenzione per ottenere un solo oggetto scrivere
Cart.find(2)
dove 2 e' l'id dell'oggetto che vogliamo trovare Tra i vari carrello
Se vogliamo ottenere una collezzione di oggetti scriveremo
Cart.find_by(argomentoDiRicerca)
l'argomento di ricerca potrebbe essere per esempio trovami tutti i carrelli con User.id=5
------------------------------------------------------------------------
HASH
h = {hashes: "awesome", ruby: "awesome", rails: "awesome"}
h.each do |key, val|
puts "#{key} => #{val}" # prints each key and value.
end
OPPURE SE ABBIAMO SOLO BISOGNO DI DELLE CHIAVI
h.each_key do |key|
puts "#{key}" # prints each key.
end
---------------------------------------------------------------------------
HOW TO CREATE A CART
LET'S SUPPOSE TO CREATE PRODUCTS
rails generate scaffold Product title:string description:text image_url:string price:integer
rake db:migrate
in the Product model we can add the following strings
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with:
%r{\.(gif|jpg|png)$}i,
message: 'must be a URL for GIF, JPG or PNG image.'
}
rails generate controller Store index
and in the file routes.rb put
get "store/index"
resources :products
root to: 'store#index', as: 'store'
and in the store controller put
class StoreController < ApplicationController
def index
@products = Product.order(:title)
end
end
in the file index.html.erb contained in view/store/ directory put
<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<h1>Your Pragmatic Catalog</h1>
<% @products.each do |product| %>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= product.price %></span>
</div>
</div>
<% end %>
CREATION OF THE CART
rails generate scaffold cart
rake db:migrate
because many users can access simultaneously, before to add a product in the cart, we need to specify the cart, otherwise we will use the same cart of other users. To do this we'll create a relation named line_item.
LET'S CREATE A RELATION BETWEEN CART AND PRODUCT
rails generate scaffold line_item product_id:integer cart_id:integer quantity:integer
rake db:migrate
in the cart model adding
has_many :line_items, dependent: :destroy
and in the line_item model adding
belongs_to :product
belongs_to :cart
Basically, we have added navigation capabilities to the model objects. Because we added the belongs_to declaration
to LineItem , we can now retrieve its Product and display the book’s title:
li = LineItem.find(...)
puts "This line item is for #{li.product.title}"
And because Cart is declared to have many line items, we can reference them
(as a collection) from a cart object:
cart = Cart.find(...)
puts "This cart has #{cart.line_items.count} line items"
Now, for completeness, we should add a has_many directive to our Product model.
After all, if we have lots of carts, each product might have many line items
referencing it. This time, we will make use of validation code to prevent removal
of products that are referenced by line items. So in the product model adding
has_many :line_items
before_destroy :ensure_not_referenced_by_any_line_item
private
# ensure that there are no line items referencing this product
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
now in the our index page located in view/store we need to add a button "Add to cart" to do this
-------------------------------------------------------------------------------------------------------
HOW TO START WEB SERVER RICK
if you want starting your webserver in other address and port:
rails s -b indirizzoDesiderato -p portaDesiderata
poidigitare da shell ifconfig individuare wlan0 e annotare l'indirizzo inet addr:
mentre nel router Alice andare su port Mapping:
creare un virtual server personalizzato come segue:
nome:localhost
ip destinazione: inetAddrAnnotatoPrima
tipo di porta: All
porta interna: 3000
porta esterna: 3000
poi dall'ipad sul browser digitare inetAddrAnnotatoPrima:3000
------------------------------------------------------------------------------------------------------------
COME ACCEDERE ACCEDERE DALLA VIEW AD UN METODO DICHIARATO IN UN GENERICO CONTROLLER
anzitutto se si vuole accedere al carrello da un link esterno occorre conoscere il path del carrello cioè cart_path
<li> <%= link_to "Carrello",cart_path(set_cart) %></li>
e poi occorre specificare l'id del carrello perche' di carrelli c'e' ne sono molti.
per recuperare l'id del carrello basta andare richimare la funzione set_cart che e' definita all'interno dell'application_controller
per richiamare una funzione dichiarata all'interno di un controller occorre scrivere cosi'
helper_method :nomeDellaFunzioneCheSiVuoleAccedereEsternamente nel nostro caso sara
helper_method :set_cart
-----------------------------------------------------------------------------------------------
SOLVED PROBLEMS
if you use link_to and turbolink this will cause a problem OF NULL ACTION
EFFECT: it won't redirect and pass anything on the address bar
is better don't use turbolink to do this delete from application.js delete the line about turbolink
HEROKU
i had the following error with heroku
remote: -----> Preparing app for Rails asset pipeline
remote: Running: rake assets:precompile
remote: rake aborted!
.
.
.
remote: ! Precompiling assets failed.
this was an compiling assets problem
I solved it inserting the following string
config.assets.initialize_on_precompile = false
in the file application.rb located under the directory config
and then beacuse I had just replaced sqlite3 with pg, my heroku db wasn't sync so from terminal I ran
heroku rake db:reset
heroku run rake db:migrate
TO DEPLOY BY HEROKU
if you don't remember the heroku site name that you have chosen in the root directory of your app from terminal digit
cat .git/config
just follow these steps:
0) from terminal digiting
git init
git add .
git commit -m "commento"
if we have already created the repository for example carello
git remote add origin https://github.com/corradt/carrello.git
git push -u origin master
1) inserting the following string
config.assets.initialize_on_precompile = false
in the file application.rb located under the directory config
2) replacing gem sqlite3 with
gem pg
3) adding gem ruby "2.2.0"
4) adding gem 'puma'
5) adding gem 'rails_12factor', group: :production
6) under the directory config in the file database.yml replacing everythig with
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5
7)in the terminal digiting
bundle install
8)from the terminal digiting
heroku create
git push heroku master
8.1) from terminal digiting
heroku rake db:reset
heroku run rake db:migrate
9) if you have any problems from terminal digiting
heroku logs --tail
and then go back to heroku page of our site and again go back to the shell to see the problem in the logs
-------------------------------------------------------------------
COME AGGIORNARE/modificare UN CAMPO senza necessariamente redirizionare l'utente in altre pagine (come edit.html.erb)
installare
gem 'best_in_place', '~> 3.0.1'
controllare in application.js se e' stata inserita la riga inerente best_in_place se non e' presente inserirla
//= require best_in_place
in carts.coffee inserire la seguente riga
$('.best_in_place').best_in_place()
se si vuole dare uno stile best questo elemento best_in_place andare su carts.scss e aggiungere
.best_in_place{
border-width:1px,80%px;
border-style:inset;
}
nella view dove si vuole modificare il valore supponendo che questo valore sia quantity
<% @ordered_products.each do |ordered_product| %>
<tr> ^
<td> |
<%= best_in_place ordered_product, :quantity, tabindex: "1" %>
</td>
<td><%= ordered_product.product_id %></td>
<td><%= ordered_product.cart_id %></td>
<td><%= ordered_product.price_per_unit %></td>
<td><%= link_to 'Destroy', ordered_product, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
dalla view best_in_place utilizza una chiamata JSON inviando attraverso il metodo PUT l'id ottenuto tramite la variabile temporanea
ordered_product
nel controllore usare JSON ed attraverso params[:id] acquisire l'id (ordered_product) passato da best_in_place nella view
def update
respond_to do |format|
format.json do
[email protected]_products.find(params[:id])
ordered_product.update_attribute(:quantity, params['ordered_product']['quantity'])
head :ok
end
end
end
QUESTA FUNZIONE DI UPDATE E MILGLIORE DELLA PRECEDENTE PERCHE' PREVIENE ATTACCHI INJECTION
def update
respond_to do |format|
format.json do
begin
quantity = Integer( params['ordered_product']['quantity'])
[email protected]_products.find(params[:id])
ordered_product.update_attribute(:quantity,quantity)
head :ok
rescue ArgumentError => e
end
end
end
end