捕获 ActiveRecord::RecordNotFound 输出 404 页面

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  rescue_from ActiveRecord::RecordNotFound, with: :render_404

  protected
  def render_404
    render(file: "#{Rails.root}/public/404.html", :layout => false, :status => 404)
  end
end
Posted in ruby on rails | Tagged , , | Leave a comment

Rails 4 Tip

RAILS_ROOTRails.root 替换

ActiveRecord 的 White list attributes 被 Strong Parameters Gem 替换

如果使用了 accepts_nested_attributes_for 应当如下使用 `Strong Parameters`

Class User
  accepts_nested_attributes_for :profile
end

# strong parameters
params.require(:user).permit(:name, profile_attributes: [:xxx, :x xx])
Posted in ruby on rails | Leave a comment

CarrierWave README

安装

安装最新稳定版

[sudo] gem install carrierwave

下面代码加入 Gemfile

gem 'carrierwave'

重启 server

CarrierWave 0.5 不兼容 Rails 2,如果你使用的是 Rails 2,请使用 github 仓库中的 CarrierWave 0.4-stable 分支

开始使用

生成一个 uploader

rails generate uploader Avatar

将会生成下面文件

app/uploaders/avatar_uploader.rb

使用 uploader 类接收和保存文件

uploader = AvatarUploader.new

uploader.store!(my_file)

uploader.retrieve_from_store!('my_file.png')

这将会保存2个文件,一个永久存储文件和一个临时存储文件。可以使用不同的存储方式,文件系统或者云存储。

多数时候 CarrierWave 会合 ORM 一起使用。在 model 类中挂载 uploader 到列上

ActiveRecord

确认 CarrierWave 已经加载,如果没有加载需要手工加载 CarrierWave (在 Rails 中通常不需要这么做)

require 'carrierwave/orm/activerecord'

添加一个字符串列到 model 中

rails g migration add_avatar_to_users avatar:string
rake db:migrate

把 uploader 挂载到列上面

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end

可以直接给属性赋值,当保存记录的时候会自动存储文件

u = User.new
u.avatar = params[:file]
u.avatar = File.open('somewhere')
u.save!
u.avatar.url # => '/url/to/file.png'
u.avatar.current_path # => 'path/to/file.png'
u.avatar.identifier # => 'file.png'

改变存储目录

重写 store_dir 方法可以改变存储目录

class MyUploader < CarrierWave::Uploader::Base
  def store_dir
    'public/my/upload/directory'
  end
end

如果要保存在顶级目录,可以给 store_dir 返回 nil

改变缓存文件保存目录

class MyUploader < CarrierWave::Uploader::Base
  def cache_dir
    '/tmp/projectname-cache'
  end
end

安全上传

使用白名单限制上传文件的扩展名

class MyUploader < CarrierWave::Uploader::Base
  def extension_white_list
    %w(jpg jpeg gif png)
  end
end
Posted in ruby on rails | Tagged | Leave a comment

Ruby 生成随机唯一字符串

Time.now.utc.to_i.to_s + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))

随机性可能不太好,唯一没问题

Posted in ruby on rails | Tagged , | Leave a comment

Linux 下面 cp/mv 为什么没有进度显示

为什么要避免在 cp 时显示进度条这种设计?

进度条显示依赖于两个关键,一是总工作量,一是当前进度量。 对于 wget 来说, 如果要获取的资源在头部有 Content-Length, 那么它可以认为获得了“总工作量”, 而具体下载过程中下载了多个字节它是知道的,这种情况下得到进度百分比是轻负担的,可承受的。

对于wget获取一个使用 http 协议的 URL 来说, 如果 Content-Length 没有指定, 则wget 也无法获取总工作量, 它所能做的只是下载一点是一点,直到收到一个结束标志。而这种情况下即使wget也无法正确显示进度条。

注: Content-Length 头在 Http 协议中是可选的.

对 于cp -a 这样的任务来说, 可能很多用把它用作备份的手段, 执行这个命令一般都是大宗买卖, 源往往是一个目录。 而获取这样一个目录的总大小是可能但不可负担的,你可以 du -csh /usr/src/linux 试试看。 在这段时间内你差不多可以复制完成了。

另一种情况, 即使要复制的源是单个的大文件,此时总工作量易于得到, 但整个copy 过程中每时每刻的工作进度则要通过不断地轮询目标文件的大小来实现。 这需要至少两个进程/线程来实现, 比较wget在内部获得这一指标来说, cost 太大了。

Posted in Linux | Tagged , , | Leave a comment

namesilo 的域名解析 ttl 默认时间48小时

48小时。。。。。

好吧,我忍,最小值3600(1个小时)

Posted in Internet | Tagged , | Leave a comment

ubuntu 无法使用php gettext的问题

今天把一台 php server 迁移服务器,新服务器使用 ubuntu,老的是 centos,在 centos下无问题, 迁移到 ubuntu 之后 php gettext 就是无法使用,表现为无法翻译内容,显示的内容还是老的。

经过检查

php-gettext

gettext

安装都正常

排查之后发现是 ubuntu 默认不支持 zh_CN 语言字符集

这里要说明一下,使用 gettext 是需要依赖系统支持的语言集,如果系统不支持 zh_CN,翻译成这种 语言根本也就无法使用了

给 ubuntu 添加 zh_CN 语言支持

/var/lib/locales/supported.d/local 文件中添加新行,内容如下

zh_CN UTF-8

然后运行 dpkg-reconfigure locales

重启 apache 之后搞定

另外说一下,查看系统支持的语言集命令

locales -a

en_US.UTF-8 UTF-8
zh_CN UTF-8
zh_CN.UTF-8 UTF-8
Posted in Linux, PHP | Tagged , , | Leave a comment

sudo cd 为什么不能工作

sudo cd 为什么不能工作

因为 cd 是 shell 内置的, 而 sudo 只能对可执行的文件起作用,也就是说在硬盘中根本没有 cd 这个文件(命令)

怎么解决呢,可以通过使用 sudo sh -c 'cd dirname' 或者 sudo -s 之后进入 root shell 之后在执行 cd dirname

Posted in Linux | Tagged , | Leave a comment

nginx client_max_body_size 的问题

遇到上传文件问题

“413 Request Entity Too Large”

查到了 nginx client_max_body_size ,原来默认值只有 1m,太小了

增大他,在 location 中添加下面设置

client_max_body_size 6m;

nginx reload, 不生效, 再试,把上面设置放 server 中,还不生效,继续放 http 中,这回生效了

这是什么问题,nginx 的文档上面明明写着 他可以放在 http server location 里面的

这是 nginx 的 bug,还是 nginx 的特性

如果是特性的话我想 http server location 只能从大到小,不能从小到大

Posted in Linux | Tagged , | Leave a comment

ActionDispatch::RemoteIp::IpSpoofAttackError

使用 unicorn + nginx 运行 rails 有一段时间了,之前 nginx 这样配置 ip 地址

proxy_set_header X-Real-IP $remote_addr;

发现 rails 中获取到的 ip 是 127.0.0.1 , 然后又配置 CLIENT_IP

proxy_set_header CLIENT_IP $remote_addr;

这样配置之后就发现了 rails 的错误

ActionDispatch::RemoteIp::IpSpoofAttackError

原来 rails 有 ip 防欺骗,再改 ningx 配置,加入

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

之后就 ok 了,想来想去这个防 ip 欺骗,是防不住的啊

Posted in ruby on rails | Tagged , , , | Leave a comment