MongoDB + Devise + Omniauth + Cancan

安装 MongoDB

Ubuntu

参考 http://docs.mongodb.org/manual/tutorial/install-mongodb-on-debian-or-ubuntu-linux/

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
$ sudo vi /etc/apt/sources.list.d/10gen.list
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen
$ sudo apt-get update
$ sudo apt-get install mongodb-10gen

启动(安装后是默认启动的)

$ sudo service mongodb start

OS X

参考 http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/

$ brew update
$ brew install mongodb

Start process

$ mongod

Open shell

$ mongo

Test

> db.test.save( { a: 1 } )
> db.test.find()

创建 Rails 应用程序(不产生Test::Unit 和 Active Record 文件)

$ rails new cho -T -O

MongoDB

在 Gemfile 加入 mongoid 相关 gems

gem "mongoid", "~> 2.4"
gem "bson_ext", "~> 1.5"

生成 mongoid 相关文件(config/mongoid.yml)

$ rails generate mongoid:config

用 scaffold 生成文章系统

$ rails g scaffold article name:string content:text

创建评论模型

$ rails g model comment name:string content:text

创建评论的控制器

$ rails g controller comments

用 scaffold 生成作者

$ rails g scaffold author name:string

Devise

在 Gemfile 加入 devise 相关 gem

gem 'devise','2.1.0'

安装 Devise

$ rails generate devise:install

创建 User 模型

$ rails generate devise User

创建 Devise 注册的视图

$ rails generate devise:views

Omniauth

在 Gemfile 加入 omniauth 相关 gems

gem "omniauth", '1.1.0'
gem "omniauth-facebook", '1.3.0'

在 Devise 的初始化文件中加入 facebook 参数

# config/initializers/devise.rb
require "omniauth-facebook"
config.omniauth :facebook, "APP_ID", "APP_SECRET", :strategy_class => OmniAuth::Strategies::Facebook

在 User 模型中释放 omniauthable

# app/models/user.rb
devise :omniauthable

在路由中定义

# config/routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
# 注意:在原来的 devise_for :users 的基础上这样改

创建 omniauth_callbacks 控制器

$ rails g controller users/omniauth_callbacks

改掉 omniauth_callbacks 控制器默认的第一行代码

# 默认
class Users::OmniauthCallbacksController < ApplicationController

# 改成这样
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

CanCan

在 Gemfile 加入 CanCan 相关 gem

gem 'cancan','1.6.7'

创建 ability.rb 文件

$ rails g cancan:ability

在 User 模型中添加角色字段

参照 https://github.com/ryanb/cancan/wiki/Role-Based-Authorization

# app/models/user.rb
field :roles_mask, :type => Integer
ROLES = %w[admin moderator author]

定义能做的事

参照 https://github.com/ryanb/cancan/wiki/Defining-Abilities

# app/models/ability.rb
# 默认
if user.admin?
# 这样改
if user.role? :admin

在 Article 控制器中控制权限

class ArticlesController < ApplicationController
  load_and_authorize_resource
  ...
end

在 Devise 注册视图中加入用户角色选项

参照 https://github.com/ryanb/cancan/wiki/Role-Based-Authorization

# app/views/devise/registrations/new.html.erb
<% for role in User::ROLES %>
<%= check_box_tag "user[roles][]", role, @user.roles.include?(role) %>
<%=h role.humanize %><br />
<% end %>
<%= hidden_field_tag "user[roles][]", "" %>

参考文章

托管代码

Advertisements

使用 wisepdf 的注意事项

wisepdf 也许不错,但初次使用以下几点不知道的话非常头疼。

1.依赖其它的 gem

光有 gem ‘wisepdf’ 不行!还得加上 gem ‘wkhtmltopdf-binary’ !

gem 'wisepdf'
gem 'wkhtmltopdf-binary'

2.不好用的配置文件例子导致的写入错误

如果从官方网站把这段代码拿过来:

Wisepdf::Configuration.configure do |c|
  c.options = {
    :use_xserver => true,
    :footer => { 
      :right => "#{Date.today.year}",
      :font_size => 8,
      :spacing => 8
    },
    :margin => {
      :bottom => 15
    }
  }
end

用 Rails 开发,development 环境没问题,production 环境就永远 error 了!
想看有什么 error,设置 config/environments/production.rb 中的 config.log_level = :debug 看,有什么500,有什么写入错误,都是这一行惹的祸:

:use_xserver => true,

它干什么的,不知道,先不去研究,干掉之!

3.生成的文件中 中文/日文 无法显示问题

这跟系统字体有关,例如 CentOS ,这样安装字体库:

yum groupinstall chinese-support
yum groupinstall japanese-support

要是安装这个出现这样的错误:

Loaded plugins: fastestmirror, priorities
Repository 'vz-base' is missing name in configuration, using id
Repository 'vz-updates' is missing name in configuration, using id
Determining fastest mirrors
Traceback (most recent call last):
  File "/usr/bin/yum", line 29, in ?
    yummain.user_main(sys.argv[1:], exit_code=True)
  File "/usr/share/yum-cli/yummain.py", line 309, in user_main
    errcode = main(args)
  File "/usr/share/yum-cli/yummain.py", line 178, in main
    result, resultmsgs = base.doCommands()
  File "/usr/share/yum-cli/cli.py", line 345, in doCommands
    self._getTs(needTsRemove)
  File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 101, in _getTs
    self._getTsInfo(remove_only)
  File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 112, in _getTsInfo
    pkgSack = self.pkgSack
  File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 662, in <lambda>
    pkgSack = property(fget=lambda self: self._getSacks(),
  File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 502, in _getSacks
    self.repos.populateSack(which=repos)
  File "/usr/lib/python2.4/site-packages/yum/repos.py", line 232, in populateSack
    self.doSetup()
  File "/usr/lib/python2.4/site-packages/yum/repos.py", line 79, in doSetup
    self.ayum.plugins.run('postreposetup')
  File "/usr/lib/python2.4/site-packages/yum/plugins.py", line 179, in run
    func(conduitcls(self, self.base, conf, **kwargs))
  File "/usr/lib/yum-plugins/fastestmirror.py", line 181, in postreposetup_hook
    all_urls = FastestMirror(all_urls).get_mirrorlist()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 333, in get_mirrorlist
    self._poll_mirrors()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 376, in _poll_mirrors
    pollThread.start()
  File "/usr/lib/python2.4/threading.py", line 416, in start
    _start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread

解决方法:vim /etc/yum/pluginconf.d/fastestmirror.conf
将其中的enabled=1修改为enabled=0。
安装软件,无错。

相关链接

用第三方社会化媒体登录你的网站

providers = %w[twitter facebook google]

1.Twitter

https://dev.twitter.com/apps

  • 必要参数

consumer_key

consumer_secret

  • 注意点

Callback URL 这样填:

http://YOUR_SITE/auth/twitter/callback

填入真实的网址在开发环境 http://0.0.0.0:3000 仍然可以确认效果

2.Facebook

https://developers.facebook.com/apps

  • 必要参数

app_id

app_secret

  • 注意点

在 Website with Facebook Login 中填入你的网址

开发环境可以填入 http://0.0.0.0:3000

3.Google

https://code.google.com/apis/console

  • 必要参数

client_id

client_secret

  • 注意点

Authorized Redirect URIs 要这样填:

http://YOUR_SITE/auth/google_oauth2/callback

开发环境不允许填入 http://0.0.0.0:3000

必要的 Gems

Gemfile

gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'

各个服务的配置

config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
  provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], { :scope => 'email,offline_access' }
  provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], { :scope => 'userinfo.email,userinfo.profile' }
end

视图中的链接

views/sessions/new.html.haml

.auth_providers
  = link_to "auth/twitter", :class => "auth_provider" do
    = image_tag("twitter_64.png", size: "64x64", alt: "Twitter")
    Twitter
  = link_to "auth/facebook", :class => "auth_provider" do
    = image_tag("facebook_64.png", size: "64x64", alt: "Facebook")
    Facebook
  = link_to "auth/google_oauth2", :class => "auth_provider" do
    = image_tag("google_apps_64.png", size: "64x64", alt: "Google")
    Google

参考链接

构建新项目(Ruby on Rails+PostgreSQL+Haml+Twitter Bootstrap)

1.安装PostgreSQL

1) Ubuntu

sudo apt-get install postgresql
sudo apt-get install postgresql-client
sudo apt-get install pgadmin3

2) CentOS

% sudo yum install postgresql postgresql-server
% sudo service postgresql initdb
% sudo service postgresql start

2.创建项目开发的用户并设置密码

1) Ubuntu

sudo -u postgres createuser $USER
sudo -u postgres psql
postgres=# password $USER

2) CentOS

% sudo su - postgres
% createuser -a {project_username}
% createdb -E UTF8 -O {project_username} {project_username}_production -T template0
% psql -c "alter user postgres with password 'abcdefg'"
% psql -c "alter user {project_username} with password 'hijklmn'"
% exit

3.安装PostgreSQL开发必要的包

1) Ubuntu

sudo apt-get install libpq-dev

2) CentOS

sudo yum install postgresql-devel

4.安装PostgreSQL Gem

1) Ubuntu

gem install pg

2) CentOS

gem install pg -- --with-pg-config=/usr/local/pgsql/bin/pg_config
※ 这种环境:
    CentOS 5
    yum install postgresql84-server

5.创建项目

rails new myapp -d postgresql

6.设置PostgreSQL允许远程访问(CentOS)

# vi /var/lib/pgsql/data/pg_hba.conf
在最后加上
host  all  all  {IP_ADDRESS}/24  md5

重启服务
/etc/init.d/postgresql restart

7.使用Haml

# Gemfile
gem 'haml-rails'

8.使用Twitter Bootstrap

# Gemfile
group :assets do
  gem 'twitter-bootstrap-rails'
end

# terminal
rails g bootstrap:install
rails g scaffold product name price:decimal --skip-stylesheets
rails g bootstrap:themed products -f

9.调整Twitter Bootstrap和will_paginate共同使用时的样式

# Gemfile
gem 'will_paginate'
gem 'bootstrap-will_paginate'

相关链接

https://help.ubuntu.com/community/PostgreSQL
http://wiki.ubuntu.org.cn/PostgreSQL
http://www.oiax.jp/rails3book/setup_postgresql.html
http://railscasts.com/episodes/328-twitter-bootstrap-basics
http://asciicasts.com/episodes/328-twitter-bootstrap-basics
http://rubysource.com/twitter-bootstrap-less-and-sass-understanding-your-options-for-rails-3-1/
https://github.com/yrgoldteeth/bootstrap-will_paginate

用 Ruby 抓取 Groupon 数据

本文限定:日本地区版

官方网站:http://www.groupon.jp/about-api/

引用:

require 'net/http'
require 'json'

抓取指定地区的优惠:

[控制器]

@coupon = Array.new
# 地区
area = Net::HTTP.get(URI("http://www.groupon.jp/api-v3/?type=area&format=json"))
@area = JSON.parse(area)
@area.each do |a|
if a["name"] == { 地区名 }
  # 优惠
  coupon = Net::HTTP.get(URI("http://www.groupon.jp/api-v3/?type=coupon&area_code=" + a["code"] + "&cid=" + a["cid"] + "&format=json"))
  @coupon << JSON.parse(coupon)
end

[视图]

<% @coupon.each do |c| %>
  <%= link_to image_tag(c["shop_img"]), c["buy_url"], :target => "_blank" %>
<% end %>