-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
1047 lines (740 loc) · 57.3 KB
/
atom.xml
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
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Ryan's Blog]]></title>
<link href="http://ryan715.github.com/atom.xml" rel="self"/>
<link href="http://ryan715.github.com/"/>
<updated>2019-04-08T23:26:28+08:00</updated>
<id>http://ryan715.github.com/</id>
<author>
<name><![CDATA[Ryan]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[创业idea-12个项目,12个项目]]></title>
<link href="http://ryan715.github.com/blog/2019/04/08/chuang-ye-idea-12ge-xiang-mu-,12ge-xiang-mu/"/>
<updated>2019-04-08T23:24:48+08:00</updated>
<id>http://ryan715.github.com/blog/2019/04/08/chuang-ye-idea-12ge-xiang-mu-,12ge-xiang-mu</id>
<content type="html"><![CDATA[<p><img src="https://danieltay.me/wp-content/uploads/2017/09/A-SPACE-_Pieter-Levels-4.jpg" alt="alt pieter levels" /></p>
<p>今天来聊下数字游民狂人Pieter Levels, 我更喜欢称他是项目狂人,因为他1年创建了12个项目,没有很强的行动力,恐怕连半数项目都做不来。12个项目当中获取有很好的创业idea,也可能激发你创业的idea,谁知道呢?</p>
<h3>Play My Inbox</h3>
<p>Levels和他朋友有个习惯,他们对于喜爱的歌曲,他们会将歌曲链接放入邮件发给对方。基于这个习惯,他开发了这个产品,将收件箱的喜爱歌曲获取出来然后循环播放。个人非常喜欢这个idea。</p>
<h3>Go Fucking Do It</h3>
<p>每个人在可接受的压力下,是可以迫使自己达到一定的目标。这个产品就是这么来的。设置一个目标和一个实际的时间,如果到了时间节点你没法达到目标,你压在网站的钱就会没收了。。。</p>
<h3>Tubelytics</h3>
<p>这个产品是一个服务自媒体的数据分析平台。实时监控并查看视频平台各频道的情况。但2015年时候这个产品就停止了。</p>
<h3>NomadList</h3>
<p>大名鼎鼎的NomadList,方便用户能够了解世界上哪个城市能够更好的生活和远程工作。主要参数有生活成本,天气(这个太重要了),网速</p>
<h3>NomadJobs</h3>
<p>只为创业公司提供的职位发布平台,并且完全按照Levels的作风,只能是远程工作。</p>
<h3>GifBook</h3>
<p>上传你喜欢的Gif图,然后将图片变成动画书,类似小时候一个动作需要画很多张图,然后快速的翻这些图,这个动作就活动起来了。有时候老外的想法比较奇特。。。</p>
<h3>Nomads</h3>
<p>一个很酷的数字游民聊天社区。在社区里面你可以了解很多世界各地的资讯。</p>
<h3>Remote|OK</h3>
<p>这个产品厉害了。主要是展示远程工作职位的,不同于传统的招聘网站,不能够发布职位,产品是采集那些远程职位然后进行展示的。</p>
<p>然后,貌似没有12个项目呢,有些栏目可能烂尾了。。。从以上项目可以看出,基本上Levels一个人活出了一个团队,很有想法的全栈的工程师。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[创业初期应该先创建网站而不是App]]></title>
<link href="http://ryan715.github.com/blog/2019/04/08/chuang-ye-chu-qi-ying-gai-xian-chuang-jian-wang-zhan-er-bu-shi-app/"/>
<updated>2019-04-08T23:11:28+08:00</updated>
<id>http://ryan715.github.com/blog/2019/04/08/chuang-ye-chu-qi-ying-gai-xian-chuang-jian-wang-zhan-er-bu-shi-app</id>
<content type="html"><![CDATA[<p><img src="https://i.loli.net/2019/04/08/5cab66310136b.jpg" alt="" /></p>
<p>作者是应用Kapwing的创始人,他和其他创始人发现视频meme非常流行,所以萌发了在线创建视频meme应用的想法。通过自己的经历,在文中一一阐述了为什么在初期需要创建网站比App重要。其中列举了4个理由。</p>
<h3>应用发布的及时性</h3>
<p>网站发布更新,线上的所有用户都可以使用,非常及时,但是App做不到,取决于用户是否安装每一次更新;另外还依赖于应用商店的政策以及审批;Apple开发者99美一年,而网站域名低于10美刀1个月。</p>
<h3>用户</h3>
<p>让用户访问一个网址远比让用户安装一个App简单。</p>
<h3>灵活</h3>
<p>创业初期,创建网站需要的经历远比开发App要少,网站只需关注浏览器,而App需要多个终端,不同型号,需要做不同适配;以及还有应用的语言,浏览器可以很简单的提供翻译功能;</p>
<h3>收费</h3>
<p>网站应用的收费会比App要高,而且应用商店会按比例收取手续费;</p>
<p>同时,文章也给出了一些情况是必须要建设App的。如应用需要读取地理信息,需要手机的能力(重力感应器之类的)或者需要频繁交易,必须保证用户登录的;</p>
<h3>文章摘自《Why Founders Should Start With a Website, Not a Mobile App》</h3>
<p>简单翻译了一下,感兴趣的同学也可以读原文或者读我的译文哈</p>
<p>当我在2012年成为斯坦福大学本科时,每个人似乎都在构建应用程序。最性感的科技初创公司–Snap,Uber,Facebook–几乎就是“app”这个词的同义词,而且世界正朝着“仅移动”软件的方向发展。移动热潮无处不在,软件=应用程序。</p>
<p>现在是2019年。应用程序的痴迷已经平静下来。与此同时,我曾在谷歌工作并创建了一个名为Kapwing的视频编辑网站,因此我对启动创业公司的情况有了更多的了解。在这篇文章中,我将分享我的观点,为什么创始人应该<em>几乎</em>总是在创业初期首先建立一个网站而不是手机应用程序。</p>
<p>去年九月,我的联合创始人和我注意到视频meme非常受欢迎,并且有几个meme原生应用程序,但没有网站帮助人们在线制作视频模因。因此,我们构建了网络的第一个视频模因生成器。几周之内,由于SEO的神奇,Kapwing每天都有数百名模因创建者使用该网站。很快,我们的用户向我们请求浏览器的其他视频编辑工具,Kapwing诞生了。</p>
<p>创业的压力让我们发现了网络的力量。我们学到了很多关于SEO,云存储的可承受性,网络技术的进步,博客以及网络生产力平台的增长。 Ilya Fushman,Dylan Field和Clark Valberg都参与了投资。现在,我们构建了一个iOS应用程序来促进视频下载,尽管几乎所有的产品开发都集中在Kapwing的网络平台上。根据我在过去15个月中在Startup Land的经验,在将您的创业公司推向市场时,您应该考虑以下事项。</p>
<p>消费者使用:移动应用与网站</p>
<p>根据谷歌和其他人的Chrome团队的研究,人们花在移动应用上的时间比在移动网站上花的时间多。应用占手机时间的90%,平板电脑的时间占77%。但应用程序的使用主要集中在一些喜欢的应用程序(eMarketer)。超过50%的消费者应用时间由Facebook或Alphabet应用程序(Apptopia)占用,90%用于一个人的五个顶级应用程序。</p>
<p>或者,在网络上花费的时间更均匀地分布在提供商和发布商之间。在浏览器中,用户可以访问他们在Google上找到的新网站,浏览现有应用中的链接以及浏览内容,而无需安装应用。因此,对于未知的初创公司来说,首次通过网络状态与本机状态联系到用户会更容易。</p>
<p>首先建立网站而不是移动应用程序的4个理由</p>
<p>根据我作为创始人的经验,网络比本机更容易起点。我建议有抱负的企业家用网站而不是原生应用来测试他们的想法,因为网站更容易构建,分发和货币化。原因如下:</p>
<p>1)建立MVP</p>
<p>即时部署</p>
<p>当Web开发人员将更改推送到其站点时,会立即部署更改,并且每个用户都会看到更新。相比之下,移动应用程序用户必须安装更新才能获得您所推送的更改,这会让用户长时间陷入错误或过时的版本。 Kapwing更加灵活,因为我们可以快速推送更新 - 甚至每天 - 无需在发布版本后面进行更改或中断用户。去年12月,就在圣诞节之后,API Kapwing意外地依赖于破产,我们在同一天发布了更改以使我们的服务重新上线。由于我们可以立即部署,意外中断只是一个小小的打嗝。如果Kapwing是一个应用程序,那么新版本需要一周的时间才能获得批准,上线,并通过应用程序更新推广给用户 - 这将是一个巨大的损失。</p>
<p>独立发布审核</p>
<p>苹果和谷歌都在过去18个月内修改了他们的开发者政策,对其商店中推荐的应用程序允许的内容提出了更严格的要求。 App Store和Google Play的批准者会更频繁地拒绝提交的内容,特别是来自与他们没有关系的未知创业公司。每当本机应用程序开发人员推送更新时,由于审核要求,他们都会面临延迟和挫折的风险。</p>
<p>当我们首次推出Kapwing iOS应用程序时,由于与产品无关的问题,需要将近2周的时间才能完成审核。例如,Apple拒绝了我们的应用程序,因为我们在App Store预览图像中使用了iPhone 8设备框架,而不是iPhone 10,这不符合Apple将图像与用户设备匹配的要求。回应“大公司”的挑剔推迟了应用程序并分散了我们的进步。相比之下,Web开发人员可以在没有外部障碍或意见的情况下推动任何变更。</p>
<p>启动成本</p>
<p>App Store开发人员许可证每年99美元,而Namecheap域名每月不到10美元。与开发成本相比,这些数字较小,但对于引导创始人而言,这一点很重要。</p>
<p>2)获得用户</p>
<p>易于分发和扩展</p>
<p>没有人想再下载应用程序了。说服某人试用您的产品的障碍对于应用而言比网站要高得多。网址可以轻松共享并显示在Google搜索中,新用户无需安装占用手机空间的软件包。</p>
<p>使用我们的移动网络应用程序,数千名用户宁愿上传视频并下载已编辑的输出,而不是在手机上安装新的照片编辑应用程序。随着我们的成长,我们已经能够扩展到其他编辑行业,因为用户可以尝试新工具而无需安装单独的应用程序。我们的用户共享其输出视频的链接和Kapwing工具的链接,在社交媒体和网络上传播有机切入点。</p>
<p>收购成本</p>
<p>在过去五年中,竞争和应用程序疲劳使应用程序的购买成本急剧上升。 Play商店中的Android应用数量在2018年3月达到顶峰。</p>
<p>自从我们去年9月推出Kapwing meme制造商以来,我们通过搜索引擎优化获得了免费的新用户,这是一个超级创始人可以访问的频道。在早期,当创始人仍在验证想法时,他们可以通过搜索利用有机获取来节省自己的痛苦和金钱。</p>
<p>3)缩放</p>
<p>适用于所有设备</p>
<p>在创业公司,工程资源很少。在不同平台上传播您的工程专业知识是昂贵的,因此最好在开始时专注于一个。为网络构建意味着移动设备,桌面设备,Chromebook(已成为美国最受欢迎的EDU硬件)以及任何其他连接互联网的设备上的用户都可以使用您的服务,而原生应用则专门针对iOS或Android。</p>
<p>建立一个网站并不意味着你放弃了移动用户;近50%的Kapwing用户来自智能手机或平板电脑。使用基于Web的产品,您的工程师可以完全使用Javascript构建,以简化开发过程,而不是使用多种不同的前端语言。</p>
<p>学生在Chromebook上使用Kapwing的网站</p>
<p>适应性强</p>
<p>如果您构建了一个拥有大量移动流量的成功移动友好型网站,您最终可以将移动用户推送到本机应用。在获得该网站的移动版本提示后,数百万活跃用户安装了Facebook,Twitter,Pinterest,Yelp,Reddit和LinkedIn应用程序。但是一个成功的原生应用程序将无法为桌面开发类似的产品,因为技术和用户行为是如此不同。构建响应式Web界面的风险较低,然后在验证您的想法后转移到本机,而不是从第一天开始使用本机。</p>
<p>国际化</p>
<p>浏览器会自动翻译文本,因此Web开发人员无需为了吸引外国用户而进行额外的工作。 Kapwing由英语使用者设计,但是,在没有我们任何额外工作的情况下,该网站每月为数万名非英语人士提供服务。网络产品免费获得国际化,这对于资金紧张的小型团队来说非常重要。原生应用团队需要弄清楚如何在国际市场上翻译和推出。</p>
<p>4)赚钱</p>
<p>桌面用户支付更高的价格</p>
<p>当您尝试通过货币化时,您将无法像在桌面上那样从移动应用中提取订阅费。专业用户希望他们的软件能够在他们的工作计算机上工作,但通常不会刷公司卡以获取纯母语应用程序。因此,网站价格可能高于应用中的相同服务。 Kapwing每月收取20美元的Pro无水印计划费用,而像Flyr TV这样的类似应用程序每月只收取5美元的高级套餐。</p>
<p>保留付款的保证金</p>
<p>构建iOS或Android应用意味着您必须为Apple或Google提供大量的应用内购买和订阅(通常为30%)。相比之下,Stripe仅占我们在网站上收取的款项的大约3%。网络支付有更多选项,因此您可以在直接向用户收费而不是通过iOS收取保证金。</p>
<p>例外:何时应该在网站上构建应用程序</p>
<p>像Startup Land中的每个决定一样,网站和原生应用之间的选择有其权衡。创始人应根据具体情况决定;有一些想法,本机应用程序有一个大腿:</p>
<p>1.位置</p>
<p>如果您的应用程序的主要价值主张与位置感知或传输相关,那么您的应用程序本质上只是移动设备,需要加入操作系统才能快速访问位置数据和传感器。示例:Lime,Bird,Uber,RunKeeper,Maps。</p>
<p>2.与本机组件紧密集成</p>
<p>如果您的价值主张与本地组件(加速度计,湿度传感器,相机,气压计,陀螺仪等)密切相关,原生应用程序将具有更好的性能和准确性。示例:指南针和相机应用程序,心率监视器,录音机,Strava。</p>
<p>3.经常需要登录的小型交易</p>
<p>如果您正在构建用户每天或每天多次执行的低触摸体验,则原生应用会消除常规登录和浏览器导航的负担。示例:习惯跟踪器,约会应用程序,Venmo,电报。</p>
<p>电子商务公司,生产力平台,发现站点,组织工具和数据聚合器不属于这些类别。大多数初创公司都没有。即使您的网站也是如此,您也可以从网站开始,看看您的用户是否要求使用原生应用。你可以随时转向本土。在这种情况下,您的网站仍然对营销和收购有价值。</p>
<p>Kapwing最初是一个网站,我们在SEO,内容营销和基于浏览器的技术上投入了大量资金。虽然我们梦想制作Kapwing病毒应用程序,但由于HTML5的最新发展,我们可以在浏览器中构建功能强大,可访问的生产力工具。如果我们可以扩展到数百万创作者,我们的用户群可能足够忠诚以吸引应用下载。在那之前,它不是,我们专注于网络。</p>
<h3>结论</h3>
<p>希望本文能够帮助年轻的开发人员重新构建他们的构思和迭代方法。作为学生,独立黑客或侧面项目骗子,快速尝试新想法和发布概念很有趣。但是,在我看来,在网络上启动这些项目比从iOS或Android开始更快,更有可能取得成功。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[How to build a ERC20 token by openzeppelin(使用openzeppelin发布erc20的加密币)]]></title>
<link href="http://ryan715.github.com/blog/2019/02/25/how-to-build-a-erc20-token-by-openzeppelin(shi-yong-openzeppelinfa-bu-erc20de-jia-mi-bi/"/>
<updated>2019-02-25T21:46:13+08:00</updated>
<id>http://ryan715.github.com/blog/2019/02/25/how-to-build-a-erc20-token-by-openzeppelin(shi-yong-openzeppelinfa-bu-erc20de-jia-mi-bi</id>
<content type="html"><![CDATA[<p>这两天重温了下ERC20,以前发布加密货币时候需要按照ERC20的要求编写相关方法以及属性,现在不需要那么复杂了。可以使用openzeppelin-solidity这个框架进行开发,十分的便捷。
入门建议看下:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="nx">pragma</span> <span class="nx">solidity</span> <span class="o">^</span><span class="mf">0.5</span><span class="p">.</span><span class="mi">2</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kr">import</span> <span class="s2">"../crowdsale/validation/CappedCrowdsale.sol"</span><span class="p">;</span>
</span><span class='line'><span class="kr">import</span> <span class="s2">"../crowdsale/distribution/RefundableCrowdsale.sol"</span><span class="p">;</span>
</span><span class='line'><span class="kr">import</span> <span class="s2">"../crowdsale/emission/MintedCrowdsale.sol"</span><span class="p">;</span>
</span><span class='line'><span class="kr">import</span> <span class="s2">"../token/ERC20/ERC20Mintable.sol"</span><span class="p">;</span>
</span><span class='line'><span class="kr">import</span> <span class="s2">"../token/ERC20/ERC20Detailed.sol"</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * @title SampleCrowdsaleToken</span>
</span><span class='line'><span class="cm"> * @dev Very simple ERC20 Token that can be minted.</span>
</span><span class='line'><span class="cm"> * It is meant to be used in a crowdsale contract.</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="nx">contract</span> <span class="nx">SampleCrowdsaleToken</span> <span class="nx">is</span> <span class="nx">ERC20Mintable</span><span class="p">,</span> <span class="nx">ERC20Detailed</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">constructor</span> <span class="p">()</span> <span class="kr">public</span> <span class="nx">ERC20Detailed</span><span class="p">(</span><span class="s2">"Sample Crowdsale Token"</span><span class="p">,</span> <span class="s2">"SCT"</span><span class="p">,</span> <span class="mi">18</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// solhint-disable-previous-line no-empty-blocks</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="cm">/**</span>
</span><span class='line'><span class="cm"> * @title SampleCrowdsale</span>
</span><span class='line'><span class="cm"> * @dev This is an example of a fully fledged crowdsale.</span>
</span><span class='line'><span class="cm"> * The way to add new features to a base crowdsale is by multiple inheritance.</span>
</span><span class='line'><span class="cm"> * In this example we are providing following extensions:</span>
</span><span class='line'><span class="cm"> * CappedCrowdsale - sets a max boundary for raised funds</span>
</span><span class='line'><span class="cm"> * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met</span>
</span><span class='line'><span class="cm"> * MintedCrowdsale - assumes the token can be minted by the crowdsale, which does so</span>
</span><span class='line'><span class="cm"> * when receiving purchases.</span>
</span><span class='line'><span class="cm"> *</span>
</span><span class='line'><span class="cm"> * After adding multiple features it's good practice to run integration tests</span>
</span><span class='line'><span class="cm"> * to ensure that subcontracts works together as intended.</span>
</span><span class='line'><span class="cm"> */</span>
</span><span class='line'><span class="nx">contract</span> <span class="nx">SampleCrowdsale</span> <span class="nx">is</span> <span class="nx">CappedCrowdsale</span><span class="p">,</span> <span class="nx">RefundableCrowdsale</span><span class="p">,</span> <span class="nx">MintedCrowdsale</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">constructor</span> <span class="p">(</span>
</span><span class='line'> <span class="nx">uint256</span> <span class="nx">openingTime</span><span class="p">,</span>
</span><span class='line'> <span class="nx">uint256</span> <span class="nx">closingTime</span><span class="p">,</span>
</span><span class='line'> <span class="nx">uint256</span> <span class="nx">rate</span><span class="p">,</span>
</span><span class='line'> <span class="nx">address</span> <span class="nx">payable</span> <span class="nx">wallet</span><span class="p">,</span>
</span><span class='line'> <span class="nx">uint256</span> <span class="nx">cap</span><span class="p">,</span>
</span><span class='line'> <span class="nx">ERC20Mintable</span> <span class="nx">token</span><span class="p">,</span>
</span><span class='line'> <span class="nx">uint256</span> <span class="nx">goal</span>
</span><span class='line'> <span class="p">)</span>
</span><span class='line'> <span class="kr">public</span>
</span><span class='line'> <span class="nx">Crowdsale</span><span class="p">(</span><span class="nx">rate</span><span class="p">,</span> <span class="nx">wallet</span><span class="p">,</span> <span class="nx">token</span><span class="p">)</span>
</span><span class='line'> <span class="nx">CappedCrowdsale</span><span class="p">(</span><span class="nx">cap</span><span class="p">)</span>
</span><span class='line'> <span class="nx">TimedCrowdsale</span><span class="p">(</span><span class="nx">openingTime</span><span class="p">,</span> <span class="nx">closingTime</span><span class="p">)</span>
</span><span class='line'> <span class="nx">RefundableCrowdsale</span><span class="p">(</span><span class="nx">goal</span><span class="p">)</span>
</span><span class='line'> <span class="p">{</span>
</span><span class='line'> <span class="c1">//As goal needs to be met for a successful crowdsale</span>
</span><span class='line'> <span class="c1">//the value needs to less or equal than a cap which is limit for accepted funds</span>
</span><span class='line'> <span class="nx">require</span><span class="p">(</span><span class="nx">goal</span> <span class="o"><=</span> <span class="nx">cap</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<ul>
<li>contract SampleCrowdsaleToken, 这是一个已经实现了ERC20的加密货币,直接is ERC20Mintable 和 ERC20Detailed就可以,具备了发行和ERC20加密货币的基本功能;</li>
<li>SampleCrowdsale 合约是一个简单的众筹合约,也是继承CappedCrowdsale,RefundableCrowdsale和MintedCrowdsale。在constructor声明相关变量就可以了。</li>
<li>OpenZeppelin 由Zeppelin主导开发,Zeppelin本身是个安全审计机构,smart contract越来越热的今天,z看准了这个市场适时推出开源框架OpenZeppelin,另OpenZeppelin也支持ERC721加密货币的开发。ERC721是什么?之前大热的加密猫就是ERC721协议的加密货币。</li>
</ul>
<p>这次简单的做个记录,下次有时间再展开讲下怎么部署ERC20token。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[capistrano puma deploy, rails console]]></title>
<link href="http://ryan715.github.com/blog/2017/04/05/capistrano-puma-deploy/"/>
<updated>2017-04-05T21:15:05+08:00</updated>
<id>http://ryan715.github.com/blog/2017/04/05/capistrano-puma-deploy</id>
<content type="html"><![CDATA[<h3>问题一</h3>
<p>最近,有个项目需要用到自动部署,就把capistrano祭出来。噼里啪啦把相关的gem安装上,配置文件拉起来,一切都是按步就班,就不一一贴出来。最后运行时候提示</p>
<p><code>Task :"puma:restart" not found.</code></p>
<p>查看了logs也没有发现有什么猫腻,到底问题出在哪里?怀疑是puma的gem上面。rails5默认自带puma gem,是不是和capistrano冲突了?</p>
<h3>解决</h3>
<p>这个提示不好搜索,也没有任何的直接的关联答案。换个思路,找几篇最近的capistrano部署的tutorials,提取里面的deploy配置文件进行对比,写法基本一致。后来排查到Capfile:</p>
<p><code>install_plugin Capistrano::Puma</code></p>
<p>缺少了这个,加上后就好了。</p>
<h3>总结</h3>
<p>开发过程中,或多或少会用到以前的一些gem,gem升级以后使用的用法会有所改变,把相关的思路再重新捋一遍,如果没有太大问题估计就是一些配置有所改变或者遗漏,一一对应即可解决问题。</p>
<h3>问题二</h3>
<p>接前面,以前用capistrano部署完了就ok,也没有想到要在项目下面运行</p>
<p><code>rails c</code></p>
<p>Rails 5 环境下是运行不起来的,那么如何才能跑起来呢?</p>
<h3>解决</h3>
<p>在 deploy 配置文件里面,把 bin 从 set :linked_dirs 移除,再添加</p>
<p><code>set :bundle_binstubs, nil</code></p>
<p>就可以解决。</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Clean Macbook]]></title>
<link href="http://ryan715.github.com/blog/2017/01/04/clean-macbook/"/>
<updated>2017-01-04T11:59:44+08:00</updated>
<id>http://ryan715.github.com/blog/2017/01/04/clean-macbook</id>
<content type="html"><![CDATA[<p>最近电脑空间告急,电脑的硬盘比较小,没办法,清理下呗~</p>
<p>之前都是使用clean mac,但这货用多后发现没啥用。</p>
<p>现在总结下:</p>
<h4>工具OmniDiskSweeper</h4>
<p>这货可以查看你的硬盘里面每个文件夹的大小,然后按大到小给你排列,你就可以根据自己的需求进行文件清理;</p>
<h4>Xcode</h4>
<p>这个文件夹真实巨硕,要想办法动下,上网查了下,发现真有可以清理的地方:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> > ~/Library/Developer/Xcode/iOS DeviceSupport
</span><span class='line'> > ~/Library/Developer/Xcode/Archives
</span><span class='line'> > ~/Library/Developer/Xcode/DerivedData</span></code></pre></td></tr></table></div></figure>
<p>这三个地方可以搞搞,wow,多了20G.</p>
<h4>参考</h4>
<p><a href="http://www.jianshu.com/p/03fed9a5fc63">http://www.jianshu.com/p/03fed9a5fc63</a>
<a href="http://www.jianshu.com/p/f27f235ed125">http://www.jianshu.com/p/f27f235ed125</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[助销宝介绍]]></title>
<link href="http://ryan715.github.com/blog/2016/09/30/zhu-xiao-bao-jie-shao/"/>
<updated>2016-09-30T10:24:12+08:00</updated>
<id>http://ryan715.github.com/blog/2016/09/30/zhu-xiao-bao-jie-shao</id>
<content type="html"><![CDATA[<h3>应用介绍</h3>
<ul>
<li>随心所欲、自由搭配diy 设计平台</li>
<li>轻松上传,搭配效果立马呈现</li>
<li>各大主流风格应有尽有,多个空间自由搭配</li>
<li>少点遗憾, 多一点出彩</li>
</ul>
<h3>联系方式</h3>
<p>如果您对产品有任何建议或者问题,欢迎发送反馈</p>
<ul>
<li>[email protected]</li>
<li>13637765022 林生</li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Some common gems for we build Ruby on Rails applications]]></title>
<link href="http://ryan715.github.com/blog/2015/10/01/some-common-gems-for-we-build-ruby-on-rails-applications/"/>
<updated>2015-10-01T11:16:53+08:00</updated>
<id>http://ryan715.github.com/blog/2015/10/01/some-common-gems-for-we-build-ruby-on-rails-applications</id>
<content type="html"><![CDATA[<p>In this post, I will share some common gems that we use for building RoR applications.</p>
<h6>bcrypt</h6>
<p>Sometimes, we build user authentication features without the use of a devise gem. To solve the storing of passwords we use bcrypt. It allows you to easily store a secure hash of users passwords.</p>
<p>Follow some steps below
1. Install
In your Gemfile, add codes below</p>
<pre><code>gem 'bcrypt'
</code></pre>
<p>then run “bundle install” commands.
2. Migrate your user table</p>
<pre><code>add_column :table_name, :password_digest, :string
</code></pre>
<p>3.Update user model file.
In your users model file, add the code below</p>
<pre><code> has_secure_password
</code></pre>
<p>That’s it.</p>
<h6>simple_form</h6>
<p>We always encounter CURD tasks when we build an admin dashboard. A simple form gem is really the best option, it can help us to solve a ton of html tags problems.</p>
<p>Basic Usage</p>
<pre><code># definition form url
<%= simple_form_for @post do |f| %>
# model collection, dropdown list html tag
<%= f.input :user_id, collection @users %>
# textfield html tag
<%= f.input :content %>
# submit
<%= f.submit '提交' %>
<% end %>
</code></pre>
<h6>annotate</h6>
<p>You don’t always know the schemas when you look at the models. Try annotate gem, it helps you to add comment summaraizing to the current schema.
When you have installed and run ‘bundle exec annotate’, you will find it is very clear to understand models. Like this:</p>
<pre><code># == Schema Information
# Table name: users
# id :integer not null, primary key
# nickname :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# password_digest :string(255)
# remember_token :string(255)
#
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
before_create :create_remember_token
</code></pre>
<h6>will_paginate</h6>
<p>In Ruby on Rails world, To develop paginate feature is really easy, will_paginate gem helps you to handle a lot of things about pagination.</p>
<p>How to use? There is a post class need to paginate.</p>
<pre><code>
# In model
@posts = Post.paginate(page: params[:paeg]
# or
@posts = Post.paginate(page: params[:page], per_page: 10)
# In page
<%= will_paginate @posts %></code></pre>
<h6>puma</h6>
<p>Unlike other Ruby Webservers, Puma was built for speed and parallelism. Puma is a small library that provides a very fast and concurrent HTTP1.1 server for Ruby web applications. It is designed for running Rack apps only.</p>
<p>You can install puma gem very easily, add codes below in your gemfile.</p>
<pre><code>gem 'puma'
</code></pre>
<p>Then start your server</p>
<pre><code>rails s Puma
</code></pre>
<h6>better_errors</h6>
<p>Provides a better page for Rails and other Rack apps. Includes sources code inspection, a live REPL and local/instance variable inspection for all stack frames.</p>
<p>After we finish installing beter_errors gem, when the error pages appear, like this:
{<1>}<img src="http://asciicasts.com/system/photos/1446/original/E402I02.png" alt="" />
Woo, It looks very nice, it helps us to find the problems exactly.</p>
<h6>rails_panel</h6>
<p>This is an extension for Chrome which adds a development log withn the brower. As we visit various pages in our application we should see an entry for each one in the panel. This works for AJAX requests too.
{<2>}<img src="http://asciicasts.com/system/photos/1450/original/E402I06.png" alt="" /></p>
<h5>capistrano</h5>
<p>Capistrano gem is a remote server automation tool. It help us to deploy a rails server more convenient.
First, you need to install the gem in your gemfile, and bundle it.</p>
<pre><cod>group :development do
gem 'capistrano', '~> 3.3.0'
gem 'capistrano-rails'
gem 'capistrano-bundler'
end
</code></pre>
<p>The second step is to initiate it.</p>
<pre><code>cap install</code></pre>
<p>The third step, the complicated step, to configure the cap file.</p>
<pre><code># config valid only for current version of Capistrano
lock '3.3.5'
set :application, '[projectname]'
set :repo_url, '[email protected]:[username]/[projectname].git'
# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/var/www/[projectname]'
# Default value for :scm is :git
set :scm, :git
set :rbenv_type, :system
set :rbenv_path, '/home/deploy/.rbenv'
set :rbenv_ruby, '2.2.0'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :default_environment, {
'PATH' => "$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
}
# puma
set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock" #accept array for multi-bind
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'staging'))
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_threads, [0, 16]
set :puma_workers, 0
set :puma_worker_timeout, nil
set :puma_init_active_record, false
set :puma_preload_app, true
# Default value for :format is :pretty
# set :format, :pretty
# Default value for :log_level is :debug
# set :log_level, :debug
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
set :linked_files, %w{config/database.yml config/secrets.yml config/env.yml}
# Default value for linked_dirs is []
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads}
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for keep_releases is 5
set :keep_releases, 5
set :keep_releases, 5
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
end
end
after :restart, :'puma:restart'
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
end
end
end
</code></pre>
<p>More details can be found at the following link in our team manual. <a href="https://zhaozijie.gitbooks.io/intro_rails/content/cong_yi_tai_kong_de_fu_wu_qi_shang_bu_shu_rails_ying_yong.html">https://zhaozijie.gitbooks.io/intro_rails/content/cong_yi_tai_kong_de_fu_wu_qi_shang_bu_shu_rails_ying_yong.html</a></p>
<h5>letter_opener</h5>
<p>When we develop mail features, we always want to preview our mail template, and we don’t want to send mail for testing. We use letter_opener gem.</p>
<p>1 Install</p>
<pre><code>gem 'letter_opener'
</code></pre>
<p>2 Configuration</p>
<p>To set the codes in config/environments/development.rb</p>
<pre><code>config.action_mailer.delivery_method = :letter_opener</code></pre>
<p>Ok, That’s it. The email will pop up in your brower, they are stored in tm/letter_openrer.</p>
<h5>rack_mini_profiler</h5>
<p>We use rake_mini_profiler gem to monitor the speed of the rails app.</p>
<p>First, add codes below to gemfile and install</p>
<pre><code>gem 'rack-mini-profiler' </code></pre>
<p>Second, there is no second step if you want :). Restart your server, and visit your app in the brower. You will find the speed data on the top-left of brower. Like this:</p>
<p>{<3>}<img src="http://ryan715.github.com/content/images/2015/09/D5059D17-B88F-40B1-9474-B774FC6F3D5E.png" alt="" /></p>
<h5>rack-attack</h5>
<p>We advise you to use the rack-attack gem to protects the rails apps. It allows you to create whitelisting, blacklisting, throttling, and tracking. Let’s add the gem to your web apps.</p>
<p>Install, add it to your Gemfile</p>
<pre><code>gem 'rack-attack'</code></pre>
<p>Set configuration in the application.rb</p>
<pre><code># In config/application.rb
config.middleware.use Rack::Attack </code></pre>
<p></p>
<p>Add custom codes to rack-attack.rb</p>
<pre><code># In config/initializers/rack-attack.rb
class Rack::Attack
# custom codes
#for example, white list
Rack::Attack.whitelist('allow from localhost') do |req|
'127.0.0.1' == req.ip
end
#for example, black list
Rack::Attack.blacklist('block 1.2.3.4.') do |req|
'1.2.3.4' == req.ip
end
end</code></pre>
<p>
About rack-attack, I will give more details in next post.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Integration ElasticSearch to Rails]]></title>
<link href="http://ryan715.github.com/blog/2015/10/01/integration-elasticsearch-to-rails/"/>
<updated>2015-10-01T11:01:21+08:00</updated>
<id>http://ryan715.github.com/blog/2015/10/01/integration-elasticsearch-to-rails</id>
<content type="html"><![CDATA[<h3>导言</h3>
<p> 这两天项目要求,把现有的搜索改成ElasticSearch(后面简称es)。之前接触 过一些es,后来就开始捣鼓。记得railcasts上面有讲过相关视频,重温了下就 开始弄,没弄多久发现上面用的<a href="https://github.com/karmi/retire">tire</a>已经retire了。为了让更多的朋友们不走冤枉路,所以才有了此文。</p>
<h3>简介</h3>
<p> 大致说下什么是es,详细的<a href="https://en.wikipedia.org/wiki/Elasticsearch">Wikipedia</a>有介绍。es其实就是一个搜索的引擎,从开源项目lucene出来,lucene是java编写的,比较复杂,要使用它必须了解核心一大堆东西。es就是包装了一层,然后提供RESTFUL API调用,从而让全文搜索变得更加简单。</p>
<h3>过程</h3>
<h5>安装</h5>
<p> 在安装es之前,先安装jdk。
Mac环境, 运行 <code>brew install elasticsearch</code>, 然后运行<code>elasticsearch --config=/usr/local/opt/elasticsearch/config/elasticsearch.yml</code>启动,访问<a href="http://localhost:9200"> http://localhost:9200</a>,访问成功就表示安装完成了。</p>
<p> 其他环境,访问<a href="http://elasticsearch.org/download">官网</a>相关安装包下载。</p>
<h5>使用</h5>
<p> 在Gemfile中加入</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="n">gem</span> <span class="s1">'elasticsearch-model'</span>
</span><span class='line'> <span class="n">gem</span> <span class="s1">'elasticsearch-rails'</span>
</span></code></pre></td></tr></table></div></figure>
<p> 注意:es-model自带了分页插件,如果你在gemfile中有分页,如<code>will_paginate</code> 或者 <code>kaminari</code>,要把他们放到es-model和es-rails的前面。</p>
<p> 在需要添加搜索的model添加以下代码:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">class</span> <span class="nc">University</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'> <span class="kp">include</span> <span class="no">Elasticsearch</span><span class="o">::</span><span class="no">Model</span>
</span><span class='line'> <span class="kp">include</span> <span class="no">Elasticsearch</span><span class="o">::</span><span class="no">Model</span><span class="o">::</span><span class="no">Callbacks</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p> 完成引用后,我们可以编写search方法了:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">search</span><span class="p">(</span><span class="n">search</span><span class="p">)</span>
</span><span class='line'> <span class="n">response</span> <span class="o">=</span> <span class="n">__elasticsearch__</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">search</span><span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p> 这是一个很简单的search,通过传入的参数直接进行检索。我们可以使用DSL来使我们的检索语句更加满足我们的业务需要,以下是我需要检索一个状态为1,并且从栏目名为name的一个检索:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">search_filter</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
</span><span class='line'> <span class="n">response</span> <span class="o">=</span> <span class="n">__elasticsearch__</span><span class="o">.</span><span class="n">search</span><span class="p">(</span>
</span><span class='line'> <span class="s2">"query"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"filtered"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"filter"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"bool"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"must"</span><span class="p">:</span> <span class="p">{</span> <span class="s2">"term"</span><span class="p">:</span> <span class="p">{</span> <span class="s2">"status"</span><span class="p">:</span> <span class="mi">1</span> <span class="p">}},</span>
</span><span class='line'> <span class="s2">"must"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"query"</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"match"</span><span class="p">:</span> <span class="p">{</span> <span class="s2">"name"</span><span class="p">:</span> <span class="n">params</span> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>关于es的DSL更多写法,大家可以访问<a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_most_important_queries_and_filters.html">这里</a>。里面详细的讲解了query,filter等一些常用查询,大家可以根据业务需要自行改装。</p>
<p> 然后我们为model创建index, 主要给es使用:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="n">mapping</span> <span class="ss">dynamic</span><span class="p">:</span> <span class="kp">false</span> <span class="k">do</span>
</span><span class='line'> <span class="n">indexes</span> <span class="ss">:name</span>
</span><span class='line'> <span class="n">indexes</span> <span class="ss">:tag</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p> 我们继续往下走,model是可以serialized成json的,我们使用<code>as_indexed_json</code>这个方法。我们可以这样写:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">def</span> <span class="nf">as_indexed_json</span><span class="p">(</span><span class="n">options</span><span class="o">=</span><span class="p">{})</span>
</span><span class='line'> <span class="nb">self</span><span class="o">.</span><span class="n">as_json</span><span class="p">(</span>
</span><span class='line'> <span class="ss">only</span><span class="p">:</span> <span class="o">[</span><span class="ss">:id</span><span class="p">,</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:description</span><span class="p">,</span> <span class="ss">:status</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="kp">include</span><span class="p">:</span> <span class="p">{</span> <span class="ss">tags</span><span class="p">:</span> <span class="p">{</span> <span class="ss">only</span><span class="p">:</span> <span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">}}</span>
</span><span class='line'> <span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p> <code>include</code>的部分是处理association的,<code>only</code>是model本身的字段属性。完成了以上调整,我们的model搜索基本完成了。如果你现在使用搜索,我估计还是搜索不出数据。我们要把数据导入给es,使用这个命令</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'> rake environment elasticsearch:import:model <span class="nv">CLASS</span><span class="o">=</span><span class="s1">'your_model_name'</span> <span class="nv">FORCE</span><span class="o">=</span>y
</span></code></pre></td></tr></table></div></figure>
<p>好啦。基本就完成。es默认自带中文分词,但是有些posts反馈说不大好用,可以使用<a href="https://github.com/medcl/elasticsearch-rtf">es-rtf</a>,集成了中文的分词插件,下载直接可以用。必须要安装jdk,里面有详尽的使用方法。</p>
<h3>相关资料</h3>
<p>gem的<a href="https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-model">README</a>,有耐心慢慢看可以了解很多</p>
<p>一些快速的tutorial</p>
<p><a href="http://www.sitepoint.com/full-text-search-rails-elasticsearch/">http://www.sitepoint.com/full-text-search-rails-elasticsearch/</a>
<a href="http://aaronvb.com/articles/intro-to-elasticsearch-ruby-on-rails-part-1.html">http://aaronvb.com/articles/intro-to-elasticsearch-ruby-on-rails-part-1.html</a>
<a href="http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/">http://www.spacevatican.org/2012/6/3/fun-with-elasticsearch-s-children-and-nested-documents/</a></p>
<p>可以了解,railcast的es介绍 <a href="http://railscasts.com/episodes/306-elasticsearch-part-1">http://railscasts.com/episodes/306-elasticsearch-part-1</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[I am back again]]></title>
<link href="http://ryan715.github.com/blog/2015/09/30/i-am-back-again/"/>
<updated>2015-09-30T17:36:05+08:00</updated>
<id>http://ryan715.github.com/blog/2015/09/30/i-am-back-again</id>
<content type="html"><![CDATA[<p>I'am back again with more passion and creative. I will record my life and code posts in here.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Dev Plan]]></title>
<link href="http://ryan715.github.com/blog/2015/09/01/dev-plan/"/>
<updated>2015-09-01T10:53:00+08:00</updated>
<id>http://ryan715.github.com/blog/2015/09/01/dev-plan</id>
<content type="html"><![CDATA[<h3>blablacar</h3>
<ul>
<li><p>Add blog features? is it nessessary?</p></li>
<li><p>public access</p></li>
</ul>
<h3>bims</h3>
<ol>
<li>Add account UI</li>
<li>Account CRUD</li>
<li>Add apple developer ios certifile </li>
</ol>
<h3>my store</h3>
<p>Helping Clare building a cake online store, to learn how to extend the spree framework.Today tasks are below</p>
<ol>
<li>change logo</li>
<li>change store name</li>
<li>search a bakery bootstrap template to custome the page</li>
</ol>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[mess, running]]></title>
<link href="http://ryan715.github.com/blog/2015/07/29/mess/"/>
<updated>2015-07-29T22:31:00+08:00</updated>
<id>http://ryan715.github.com/blog/2015/07/29/mess</id>
<content type="html"><![CDATA[<h3>About Mess</h3>
<p>Today devotional is about Whose mess, it descrips some mess form our spiritually sense. It teaches us that do not judge people, cause we usually ignore our sin instead other’s sin.</p>
<h3>Running</h3>
<p>I run today, but I don’t want to run before. I run so fast today, I think the reason is that i didnot run so long time. Feeling so good after running.</p>
<h3>Exploitting market</h3>
<p>How to exploit market? The biggest problem after your company starts business. I wrote down some key points after conclued below</p>
<ul>
<li>The product is the important thing, you must understand the selling points about products clearly.</li>
<li>Introduction your businesses to freinds or clients who worked before, telling them what they got it from products, the product how to solve their problems.</li>
<li>You need a website to present the product demo.</li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[subdomaininrails4]]></title>
<link href="http://ryan715.github.com/blog/2014/11/28/subdomaininrails4/"/>
<updated>2014-11-28T17:27:00+08:00</updated>
<id>http://ryan715.github.com/blog/2014/11/28/subdomaininrails4</id>
<content type="html"><![CDATA[<p>Today, i’ll blog something about subdomain in rails4.</p>
<h1>subdomain.rb</h1>
<p><<<<<<< HEAD
you should add sobdomain.rb</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>class
</span><span class='line'> def
</span><span class='line'>
</span><span class='line'> end
</span><span class='line'>=======
</span><span class='line'>you should add sobdomain.rb ```
</span><span class='line'>class Subdomain
</span><span class='line'>
</span><span class='line'> def
</span><span class='line'>
</span><span class='line'> end
</span><span class='line'>
</span><span class='line'>>>>>>>> 4d8aefe0d00b747da16710d2077593dfd55bdc68
</span><span class='line'>end</span></code></pre></td></tr></table></div></figure>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[hello again]]></title>