这里有我的脚丫印😄

程序媛


  • 首页

  • 归档

acts-as-taggable-on 生成标签

发表于 2016-08-31 |

step1:安装gem

把下面这句话放入Gemfile中

1
gem 'acts-as-taggable-on'

step2.在终端(terminal)中执行

1
2
3
bundle install
rake acts_as_taggable_on_engine:install:migrations
rake db:migrate

这会生成tags和taggings这两张表。在schema.rb中可以查看。

step3.在自己需要加标签的model中加入

1
2
3
class Post < ActiveRecord::Base
acts_as_taggable_on :tags
end

在rails console中可以执行看看效果

1
2
3
post = Post.create
post.tag_list = "programming, ruby, rails"
post.tag_list

执行结果:

1
['programming', 'ruby', 'rails']

新增时tag_list是一个以逗号相隔的string(字符串),在新增tag的时候,只需填入tag的名称,以逗号相隔做成字符串,后面的一系列操作这个gem自动都给你处理了。

(会通过taggings这个表连接tags和posts的关系,而且仔细看tags的表结构可以看到name: “index_tags_on_name”, unique: true,也就是tags的name字段是唯一的,所以不会重复添加同名的标签)

step4:post_controller

在新增post的时候,把tag_list加入Strong Parameters(强校验)

1
2
3
4
5
6
7
8
9
class PostsController < ApplicationController
...
private
def post_params
params.require(:post).permit(:title, :content, :tag_list)
end
end

step5.配置路由

config/routes.rb

1
2
3
4
Rails.application.routes.draw do
resources :posts
resources :tags, only: [:index, :show]
end

step6. 以下是view,可以参考一下

app/views/posts/_form.html.erb (在新增post时候加入tag_list即可。如果想做成下拉框select标签时,请注意,强校验不会接受hash类型,并且tag_list也只能是逗号相隔的字符串才行,所以,要在强校验之前,把tag_list处理成相应格式)

1
2
3
4
5
6
<%= form_for post do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body %>
<%= f.text_field :tag_list %>
<%= f.submit %>
<% end %>

app/controllers/tags_controller.rb

1
2
3
4
5
6
7
8
9
10
class TagsController < ApplicationController
def index
@tags = ActsAsTaggableOn::Tag.all
end
def show
@tag = ActsAsTaggableOn::Tag.find(params[:id])
@posts = Post.tagged_with(@tag.name)
end
end

app/views/acts_as_taggable_on/tags/_tag.html.erb

1
<%= link_to tag.name, tag_path(tag) %>

app/views/tags/index.html.erb

1
2
<h1>Tags</h1>
<%= render @tags %>

app/views/tags/show.html.erb

1
2
<h1><%= @tag.name %></h1>
<div><%= render @posts %></div>

app/views/posts/_post.html.erb

1
<h2><%= link_to post.title, post_path(post) %></h2>

app/views/posts/index.html.erb

1
2
<h1>Posts</h1>
<%= render @posts %>

app/views/posts/index.html.erb

1
2
3
4
<%= post.title %>
<%= post.content %>
<h4>Tags</h4>
<%= render post.tags %>

app/views/posts/show.html.erb

1
2
3
<h1><%= @post.title %></h1>
<div><%= @post.body %></div>
<div><%= render @post.tags %></div>

补充:

1
2
@tags = current_user.tags
@hot_tags = Tag.where.not(id:@tags)

用这个筛选掉已经关注的的tags(在这个地方纠结,想通过Tag.all-@tags,但是没有成功。有可能是@tags gem做了什么关联,查出来的对象不一致,或者是不能用减做对象的集合操作,有待查证)

1
2
3
#取消标签
current_user.tag_list.remove(@tag.name)
current_user.save

新增单个标签

1
2
3
@tag = Tag.find(params[:id])
current_user.tag_list.add(@tag.name)
current_user.save

新增多个标签,参数是数组形式时

1
2
3
4
5
6
7
tag_list = params[:tag_list]
if tag_list
#数组要转成逗号相隔的字符串
tag_list = tag_list.map{|k,v| "#{k}#{v}"}.join(',')
current_user.tag_list = tag_list
current_user.save
end

dropdown

发表于 2016-08-30 |

f.input 是simple_form_for的使用

这个是普通的下拉:

1
<%= f.input :tag_list,collection: @tags %>

下面这个是加了semantic-ui的下拉框(多选)

1
<%= f.input :tag_list,collection: @tags,label:"问题标签",input_html: { class: 'ui fluid search dropdown',multiple: "" } %>

html

1
2
3
4
<select class="ui fluid search dropdown" multiple="">
<option value="">State</option>
<option value="">State</option>
</select>

效果图:
屏幕快照 2016-08-30 下午1.19.20.png

下面这个是带搜索的semantic-ui下拉(多选)

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
<div class="ui multiple dropdown" id="dropdown">
<input type="hidden" name="filters" value="<%=@filters%>">
<i class="fa fa-users" aria-hidden="true"></i>
<span class="text" style="color:#adda4d" id="invite">邀请回答</span>
<% unless @invitated_users.nil? %>
<% @invitated_users.each do |user| %>
<a class="ui label transition visible" data-value="<%= user.id %>" style="display: inline-block !important;">
<%= gravatar_tag user.email, :size => 50, :default => avatar_url %>
<%= user.name %>
回答数量:<%= user.answers.count %>
<i class="delete icon"></i>
</a>
<% end %>
<% end %>
<div class="menu">
<div class="ui icon search input">
<i class="search icon"></i>
<input type="text" placeholder="搜索你想提问的学长学姐">
</div>
<div class="divider"></div>
<div class="header">
<i class="tags icon"></i>
学长&学姐
</div>
<div class="scrolling menu">
<% @users.each do |user| %>
<div class="item" data-value="<%= user.id %>">
<%= gravatar_tag user.email, :size => 50, :default => avatar_url %>
<%= user.name %>
回答数量:<%= user.answers.count %>
</div>
<% end %>
</div>
</div>
</div>

效果图:

屏幕快照 2016-08-30 下午1.32.30.png

这是一个二级下拉

1
2
3
4
5
6
7
<%= f.input :author,
:as => :grouped_select,
:collection => [['Authors', ['Jose', 'Carlos']], ['General', ['Bob', 'John']]],
:group_method => :last %>

效果图:
屏幕快照 2016-08-30 下午1.14.49.png

json在view中解析

发表于 2016-08-28 |
data
1
2
3
4
5
6
data = $.parseJSON(data); //把json字符串解析成json对象
jquery中的遍历
$.each(data, function(index, user) {
var email = user.email;
alert(email);
});

Array

发表于 2016-08-28 |

集合操作

x = MultiSet.new([1,1,2,2,3,4,5,6])
y = MultiSet.new([1,3,5,6])

x - y => [2,2,4] 差集
x & y => [1,3,5,6] 交集
x | y =>[1,2,3,4,5,6] 并集

a = [1,2,3]
a.any?
=> true

a.clear
a.any?
=> false

[nil, 1].any?
=> true
[nil, nil].any?
=> false

a = []
=> []
a.empty?
=> true
a = [nil, false]
=> [nil, false]
a.empty?
=> false
a = [nil]
=> [nil]
a.empty?
=> false

Model

发表于 2016-08-27 |

followees << followee 加入收藏夹,加入关系
followees.delete(followee) 移出收藏夹,删除关系

def
  @users = User.all
end

转换成1,2,3这种字符串
params[:question][:tag_list].map{|k,v| “#{k}{v}”}.join(‘,’)

站内信

发表于 2016-08-24 |

1.创建model

rails g model notification

添加 migration

class CreateNotifications < ActiveRecord::Migration[5.0]
  def change
    create_table :notifications do |t|
      t.integer :recipient_id
      t.integer :actor_id
      t.datetime :read_at
      t.string :action
      t.integer :notifiable_id
      t.string :notifiable_type

      t.timestamps
    end
  end
end

rake db:migrate

补充model

class Notification < ApplicationRecord
   belongs_to :recipient, class_name: "User"
   belongs_to :actor, class_name: "User"
   belongs_to :notifiable, polymorphic: true

   scope :unread, -> { where(read_at: nil) }
   scope :recent, -> { order(created_at: :desc).limit(5) }
 end

2.创建controller

rails g controller notifications



class NotificationsController < ApplicationController  
  before_action :authenticate_user!
  def index
    @notifications = Notification.where(recipient: current_user).recent
  end

  def mark_as_read
    @notifications = Notification.where(recipient: current_user).unread
    @notifications.update_all(read_at: Time.zone.now)
    render json: { success: true }
  end
end

3.在notifications.coffee中加入

class Notifications

  constructor: ->

@notifications = $("[data-behavior='notifications']")

if @notifications.length > 0
  @handleSuccess @notifications.data("notifications")
  $("[data-behavior='notifications-link']").on "click", @handleClick

  setInterval (=>
    @getNewNotifications()
  ), 5000

  getNewNotifications: ->
$.ajax(
  url: "/notifications.json"
  dataType: "JSON"
  method: "GET"
  success: @handleSuccess
)

handleClick: (e) =>
$.ajax(
  url: "/notifications/mark_as_read"
  dataType: "JSON"
  method: "POST"
  success: ->
    $("[data-behavior='unread-count']").text(0)
)

handleSuccess: (data) =>
  items = $.map data, (notification) ->
    notification.template

  unread_count = 0
  $.each data, (i, notification) ->
    if notification.unread
      unread_count += 1

  if unread_count > 0
    $("[data-behavior='unread-count']").html("<span class='label label-danger'>" + unread_count + "</span>")
  else
    $("[data-behavior='unread-count']").text(unread_count)
  $("[data-behavior='notification-items']").html(items)

jQuery ->

  new Notifications

4.在notifications.scss中加入

.unread {
 border-left: 3px solid red;
}

5.创建notification_service.rb

NotificationService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class NotificationService
# recipient 接收者
# actor 发起者
# notifiable 哪张表发起的 比如,question要提醒用户,这里就传question
def initialize(recipient, actor, notifiable)
@recipient = recipient
@actor = actor
@notifiable = notifiable
end
# 发送信息
def send_notification!
Notification.create(recipient: @recipient, actor: @actor, action: "notify_message", notifiable: @notifiable)
end
end

6.创建app/views/notifications/questions/_notify_message.html.erb
如果需要另外一个model也发送
创建app/views/notifications/answers/_notify_message.html.erb

比如,app/views/notifications/questions/_notify_message.html.erb,这里展示消息要呈现的内容

1
2
3
4
5
6
7
<div class="panel-body">
<%= notification.actor.name %> 邀请您回答他的问题
<%= link_to("去回答",new_question_answer_path(notification.notifiable_id)) %>
</div>

_notify_message.html.erb 的名字需要和
需要和action: “notify_message”一致,看一下notifications的表结构中有action的字段

questions的目录和要发送的model一致

7.在需要发送消息的地方调用service

1
2
3
#将会把@question的id和model('Question')的名字存入notifications的#notifiable_id和notifiable_type
NotificationService.new(user,current_user,@question).send_notification!

或者

# 将会把@answer的id和model的名字('Answer')存入notifications的
# notifiable_id和notifiable_type
NotificationService.new(@question.user,current_user,@answer).send_notification!

link_to

发表于 2016-08-24 |
1
2
3
4
5
6
7
关注
```<% if !current_user.already_follower?(@user) %>
<i class="fa fa-heart" aria-hidden="true"></i>
<% else %>
<i class="fa fa-heart-o" aria-hidden="true"></i>
<% end %>
<% end %>
1
2
3
4
5
6
7
8
9
10
```ruby
<%=link_to_if(question.answers.count>0, "删除"
,publish_hidden_account_question_path(question)
, method: :post, data: { confirm: 'Are you sure you want to delete the question?' }
, class:"btn btn-primary btn-xs",disabled:true) do
link_to("删除",publish_hidden_account_question_path(question), method: :post
, data: { confirm: 'Are you sure you want to delete the question?' }
, class:"btn btn-primary btn-xs")
end %>

semantic-ui引用到rails

发表于 2016-08-24 |

参考:
https://github.com/doabit/semantic-ui-sass
http://semantic-ui.com/

1.安装gem
gem ‘semantic-ui-sass’, github: ‘doabit/semantic-ui-sass’
bundle install

2.引用到项目中
app/assets/stylesheets/application.scss 中加入

"semantic-ui";```
1
2
3
app/assets/javascripts/application.js 中加入
```//= require semantic-ui

3.去官网找到一些demo,实现效果
http://semantic-ui.com/introduction/getting-started.html

比如找到dropdown,下面截图是多选下拉的效果(可以自己点开网页中的按钮试一试)

屏幕快照 2016-08-24 上午11.01.32.png

屏幕快照 2016-08-24 上午11.01.22.png

屏幕快照 2016-08-24 上午11.04.28.png

下面这个是启用js效果的示例

屏幕快照 2016-08-24 上午11.04.58.png

我是这样写的,在我的页面中加入,这样就把官网的示例引用成功了

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
<script type="text/javascript">
$(function(){
$('.ui.dropdown')
.dropdown({
allowAdditions: true
});
});
</script>
<div class="ui multiple dropdown">
<input type="hidden" name="filters">
<i class="filter icon"></i>
<span class="text">Filter Posts</span>
<div class="menu">
<div class="ui icon search input">
<i class="search icon"></i>
<input type="text" placeholder="Search tags...">
</div>
<div class="divider"></div>
<div class="header">
<i class="tags icon"></i>
Tag Label
</div>
<div class="scrolling menu">
<div class="item" data-value="important">
<div class="ui red empty circular label"></div>
Important
</div>
<div class="item" data-value="announcement">
<div class="ui blue empty circular label"></div>
Announcement
</div>
<div class="item" data-value="cannotfix">
<div class="ui black empty circular label"></div>
Cannot Fix
</div>
<div class="item" data-value="news">
<div class="ui purple empty circular label"></div>
News
</div>
<div class="item" data-value="enhancement">
<div class="ui orange empty circular label"></div>
Enhancement
</div>
<div class="item" data-value="off-topic">
<div class="ui yellow empty circular label"></div>
Off Topic
</div>
<div class="item" data-value="interesting">
<div class="ui pink empty circular label"></div>
Interesting
</div>
<div class="item" data-value="discussion">
<div class="ui green empty circular label"></div>
Discussion
</div>
</div>
</div>
</div>

4.把选择的值传入controller
注意到有这一行

1
<input type="hidden" name="filters">

通过网页右键检查,可以看出添加的value都会以

1
2
面。那么在controller里面就可以通过params[:filters]接收。
可以转换成数组

# 这个是字符串
filters = params[:filters]

#这里是转化成数组
filters_array = filters.split(“,”)

后面就可以做自己需要做的了

1
2
并且要注意这一行,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
这里是用data-value里面的值作为选择后放入filters的元素。比如这里是data-value="interesting",那么选中它之后
就会在filters中加入interesting。
5.编辑页面回显
用这种方式可以设置默认值或者是回显的值
//$('.ui.dropdown').dropdown('set selected',['Role1','Role2']);
用这个会自动给生成 a 标签,这个和在filters中赋值回显回来的效果一样
这两种方法显示的内容我不知道如何让它像我新增时那样丰富
所以没有用这两种,用的下面的这个,当data-value一致时会把自动生成的给覆盖掉
```<% unless @invitated_users.nil? %>
<% @invitated_users.each do |user| %>
<a class="ui label transition visible" data-value="<%= user.id %>" style="display: inline-block !important;">
<%= gravatar_tag user.email, :size => 50, :default => avatar_url %>
<%= user.name %>
回答数量:<%= user.answers.count %>
<i class="delete icon"></i>
</a>
<% end %>
<% end %>

这样就回显成功了。

当取消掉或新增,进入update方法时,需要比较一下,新增的有哪些,取消的有哪些,取消的要从数据库中删掉,新增的再插入数据库。

我用的是 并集 = 新的集合 | 数据库中老的集合
需要新插入数据库的集合 = 并集 - 数据库中老的集合
需要删除的集合 = 并集 - 新的集合

然后分别对新增和删除的集合进行Model运算

暂时这样,应该可以说清楚了。

heroku上管理密码

发表于 2016-08-14 |

安装 figaro

>figaro 是一個方便管理机密信息、密码的gem,并且能一个指令就将机密信息同步到 heroku 上
step1: 添加gem figaro  到Gemfile文件中
   bundle install
   figaro install

step2: 设定机密信息
cp config/application.yml
config/application.yml.example
修改 .gitignore, 加入config/application.yml

原理是把机密信息填入config/application.yml ,通过加入.gitignore,从而不会把此机密文件上传到github公开。

这次上传文件用的是AWS,这里涉及秘钥及信用卡安全,所以,这次是把秘钥藏在这个application.yml文件中,然后通过配置文件,从这个application.yml文件中读取秘钥等信息。

Step 3: 将设定好的机密信息同步到 heroku
figaro heroku:set -e product
heroku config 可以列出目前所有的設定

这一步是把我们的隐秘信息告诉heroku,从而把这些机密藏入heroku配置环境中,被隐藏起来。

Step 4: 重新 git commit & push to heroku
要再一次 commit & push to heroku 这些设置才会生效

产品用户调查

发表于 2016-08-14 |

产品服务:私人形象顾问

简要:根据不同收入水平,综合定位符合用户气质的服饰、发型、妆容等形象设计。
适用于特殊场合或者日常生活。

产品宗旨:让你更美丽自信。
不只是明星才能拥有私人形象顾问,变得美美的,你也可以。
不只是结婚或者什么才需要隆重打造,让平时的日子就各种美妙。
你可以小清新,也可以美丽动人,让自己更好的展现在人前。
拥有自己的品味和风格。

解决的客户烦恼:
1).日常生活体现不了自己的品味和风格。
比如:
1.花了大把时间仍买不到自己满意的服装
2.不想花太多的时间在形象上面,却又想变得美美的
3.想换一种风格的
4.不会或不敢化些淡妆和日常保养
2).特殊场合无法更好的打造个人形象。
比如:
1.想给特殊的日子换一个惊艳的装束,给爱人惊喜。
2.参加某个party,想最好的展现自己的魅力。
3.参加什么会议正确快速租赁适合这个场合的服饰

运作原理:
1.线上咨询,会有专有的私人形象顾问服务,描述自己的形象方面的烦恼,通过上传个人照片,报告身高体重,或者自己想成为的摸样,通过不断的了解,给予专业的建议。
2.可以线下预约,快速定位符合自己的妆容,服饰和搭配等。
3.如果想培养自己的品味意识等,可以购买中长期服务。
4.提供针对个人的专业化教学培训。关于教会化妆,教会选购服饰,教会日常保养。

當你在做 OOO時,你最討厭的事情是什麼? <== 這個OOO是痛點環境
當你學會、買到、知道 XXXX 後,你最想要做什麼事? <== 這個XXXX是 學員所提供的服務
當你用了,做了,學會 XXXX,完成了什麼事後。你最想要達成什麼目標?<== 這個XXXX 同上一題的XXXX

问卷调查:
当被这个产品服务的时候:
A: 痛点:不能被过度收费;
不能被过度推销
需要有合适的人量身定做
最讨厌的是:收费过高,搭配的还不如自己搭配的。过度推销。
最想做的是:自己挑衣服很麻烦也很难挑到合适的,想通过这个节省时间,提升形象。
最想达成的目标:服务之后,能被别人称赞自己的品味,每个季度都能收到合适的衣服推荐。

B:最讨厌的是: 被推销产品
最想做的是:出席特殊场合。快速租赁衣服和适合的形象设计。
最想达成的目标:平时的时候,根据我的收入,提供合理化的服饰搭配意见,以最实惠的价格找到最适合的衣服。
担心的是:如果服务过后,自己不满意能不能退货什么的。

C:最讨厌的是: 推荐的东西不符合我的收入
最想做的是:知道一些搭配打扮的知识
最想达成的目标:通过平台提升个人品味,愿意花金钱时间在个人形象的提升

D:最讨厌的是:涉及过多的个人隐私,揭露自己的缺点
最想做的是:获得专业的个人形象咨询服务,了解不同场合应该以怎样的面貌出现。
最想达成的目标:提高个人审美能力,让自己更自信

E: 不需要类似服务:
知道自己最适合什么。能够花在这上面的钱还不如自己去花在衣服和具体的实物上面。
不足够有钱,不了解自己的人,有可能不能给自己最合适的建议。
这应该适合不喜欢买买买的女人和不会买买买的女人。

F: 最讨厌的是:价值观不一样,推荐的款式不对口,方案单一。
最想做的是:出席重要场合,给指导意见
最想达成的目标:提升个人形象,节省时间

G:最讨厌的是:花了钱没效果
最想做的:服务专业
最想达成的目标:出门就能装逼

H: 最讨厌的是:把自己包装的一塌糊涂
最想做的是:设计包装自己的形象
最想达成的目标:包装到自己满意的效果

1…6789

陈云莉 m18301662790@gmail.com

记录一些技术点,留下一些生活感悟

82 日志
25 标签
© 2017 陈云莉 m18301662790@gmail.com
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.3