Rails
0.app初始化时bundler require的细节,参考这个文章
https://stackoverflow.com/questions/4800721/bundler-what-does-require-false-in-a-gemfile-mean
1.rails new #projectname#
2.bundle install (--without) production //安装依赖
3.rails generate controller MyTest test1 test2
将生成my_test_controller.rb,在该文件中有指向test1和test2的路由,还将生成这些文件对应的css,js和html模板
通过rails destroy controller MyTest可以撤销。
4.app/views/layouts/applicaiton.html.erb是整个网站的模板。
5.<% provide(:symbol,"aaa") %>设置一个页面变量
6.<%= yield(:symbol) %>将页面变量输出到页面中
7.通过<%= render 'erb_path'%>来引入外部partial文件,partial文件需要以underscore开头
8.get "test" "test#function1" 来获取一个named route,这样test_path将指向 test/function1.html.erb,test_url将在redirect的时候使用
9.assert_select语法
Matching HTML |
|
assert_select "div" |
foobar |
assert_select "div", "foobar" |
foobar |
assert_select "div.nav" |
|
assert_select "div#profile" |
foobar |
assert_select "div[name=yo]" |
hey |
assert_select "a[href=?]", ’/’, count: 1 |
foo |
assert_select "a[href=?]", ’/’, text: "foo" |
foo |
10,
rails generate系列
rails generate controller controller_name func1 unc2...
rails generate integration_test testname来书写一个整合测试,测试时使用rake test:integration
rails generate model Model_class field1:type1 field2:type2 ...
rails generate migration #migration_file_name (i.e add_index_to_users_email) //rails会在db目录下生成一个新的migration文件,内容需要自己填写,如
class AddIndexToUsersEmail < ActiveRecord::Migration def change add_index :users, :email, unique: true end end
rake db:migrate将model同步到数据库
rails generate migration add_*_to_table_name/ remove_*_from_table_name rails命令识别这两种pattern,但是*处他将忽略
11.rails console --sandbox 类似irb,不过通过该控制台可以访问当前rails项目的环境,--sandbox帮助我们可以对数据库进行任何操作,但是当console退出时全部rollback
12.见active_record
13,通过validates方法给model添加验证
validates :name, presence:true //name不可以是空
可以通过查看验证错误信息。注意,不调用valid?方法就看不到该信息
if !user.valid?
puts user.errors.full_messages
end
14.可以通过参数来指定当前ruby的运行环境,但是不同场景下参数传递方式不同
rails console test(production/development) --sandbox
rails server --environment production
rake db:migrate RAILS_ENV=production
在rails中可以通过Rails.env来获取当前环境
15.ruby里面定义一个resource user,需要在routes.rb中定义
resources :users
然后再users_controller.db中定义所有方法,方法名是有规定的
HTTP request | URL | Action | Named route | Purpose |
GET | /users | index |
users_path |
page to list all users |
GET | /users/1 | show |
user_path(user) |
page to show user |
GET | /users/new | new |
new_user_path |
page to make a new user (signup) |
POST | /users | create |
users_path |
create a new user |
GET | /users/1/edit | edit |
edit_user_path(user) |
page to edit user with id 1 |
PATCH | /users/1 | update |
user_path(user) |
update user |
DELETE | /users/1 | destroy |
user_path(user) |
delete user |
加入byebug gem,在代码中加入debugger,刷新页面,查看rails控制台,即可进行调试,按ctrl+d退出调试上下文
17.ruby从4.0之后引入了强保护参数,可以通过
params.require(:user).permit(:name,:email)的方式限制。
这段代码的意思是表单中params会有类似
"user" => {
"name"=>"aa",
"email" =>"[email protected]",
"admin" => 1//过滤这个属性,防止被攻击
}
的属性,require要求params中必须有user,没有就会报错,另外只允许name和email属性
18.提交表单发生错误时,错误的域会被包上一层
field_with_errors">
19.assert_template的参数例子 assert_template "users/new"
assert_difference "User.count",1 do
@user.save
end
20.rails中可以通过form_for方法生成form,
form_for @user do |f|
f.label :name
f.textfield:name
end
该函数有两个重载
form_for @user, 这样,他会将action设置为@user的类(User类)的小写形式user,另外加上path,即user_path,除此之外,上面的f.textfield会生成
另一个重载使用场景为session,因为session不是一个ActiveRecord
form_for "session",login_path //第一个参数用于生成input时候的上下文对象,,第二个参数用于生成action
21. 使用下面这个方法生成一个base64的随机串
def User.new_token SecureRandom.urlsafe_base64 end
22.rails为Fixnum添加了不少和时间,单位有关的函数
1.year.from_now
1.year.ago
可以用来获得相对应的时间对象
23.通过Bcrypt类库来创建密码加密
BCrypt::Password.create(string, cost: cost)
然后使用来比较
BCrypt::Password.new(self.remember_digest).is_password?(remember_token),
其实可以使用下面语句,因为==被重写成了使用is_password?方法
BCrypt::Password.new(self.remember_digest) == (remember_token)
23.可以在db/seed.rb中定义数据库中的初始化数据,然后运行rake db:seed来初始化,
可以使用faker来创造假名字
gem 'faker', '1.4.2'
99.times do |n| name = Faker::Name.name email = "a#{n + 1}@a.com" password = "qiuqiu" User.create!({name: name, email: email, password: password}) end
用
Faker::Lorem.sentence(number)来创造假句子
24.rails可以简化一下迭代运算
class="users">
<% @users.each do |user| %>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% end %>
首先我们可以将 class="users">
<% @users.each do |user| %>
<%=render user%>
<% end %>
,进一步,可以把@users.each也简化了,直接为
class="users">
<%= render @users%>
<%= link_to "delete", user_path(user), method: :delete, data: { confirm: "You sure?" } %>26.在一个model里可以定义before_save,before_create。
27.利用rails定义邮件模板十分便利,
1.利用rails generate mailer UserMailer activate_user reset_password
该命令将在app/mailers文件夹下新建一个UserMailer的“控制器”,
2.可以修改里面的代码设置发件人和模板中将使用的对象
def account_activation(user) @user = user #该对象将被用在模板中 mail to: user.email, subject: "Account activation" end
3.修改模板的值,模板位于app/views/user_mailer,可以使用<%%>或者<%=%>插入变量
4.rails允许预览邮件,那么需要修改环境文件中关于预览的配置,修改config/environment/development中加入
config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :test host = 'localhost:3000' config.action_mailer.default_url_options = {host: host}
5.重启rails服务器,打开test/mailer/previews,可以发现rails已经为我们建立了一个预览文件,稍许做修改就可以打开浏览器访问预览,地址在该文件中也有
6.最后,一切测试成功后,在注册的函数中修改逻辑
def create @user = User.new(filter_user_params) if @user.save UserMailer.create_account_activation(@user).devlier_now flash[:success] = "Please activate your account" redirect_to root_path #不再自动登录 else render 'new' end end
28.表单中设置一个hidden域。
<%= hidden_field_tag :email, @user.email %> 第一个参数为name,第二个参数为value
同样也可以使用f.hidden_field,两者的区别是第一种形式的话,email参数将通过params[:email]获得,而后者需要查看form的第一个参数,如果第一个参数是一个对象,比如是User类型,那么email将通过params[:user][:email]获得,如果他是一个string,如aaa,则通过params[:aaa][:email]获得
33.
当一个Events要访问一个Category时,可以使用event.category_name,这需要在Event的model李注明以下信息
delegate :id, to: "category", prefix: true, allow_nil: true
34.
生成一个checkbox,name为ids[],值为event.id,false为不勾选
<%= check_box_tag "ids[]", event.id, false %>
35.当controller发生错误时,开发环境下显示堆栈,prod显示错误页面,当然也可以覆盖这种行为
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordInvalid, :with => :show_error
protected
def show_error
# render something
end
end
36.Rails国际化
在config/initializers下创建i18n.rb,内容如下
I18n.default_locale = :en LANGUAGES = [ ['English', 'en'], ['Español', 'es'] ];在route.rb中定义包含locale信息的路由
scope '(:locale)' do
resources A
controller B do
end
end
在Application.controller中定义以下两个方法
def set_i18n_locale_from_params
#当url中包含locale信息时,更新locale if params[:locale] if I18n.locale_available?(params[:locale]) I18n.locale = params[:locale] else flash.now[:notice] = "#{params[:locale]} translation not available" logger.error flash.now[:notice] end end end
#网页生成链接时会调用此方法 def default_url_options { locale: I18n.locale } end
41.Render方法
render nothing:true
render :new, content-type:...,status:201,layout:...
render_to_string 可以把页面渲染在string中,接受的参数和render是一样的,但是他不会被认作是真正的render,不会发生DoubleRenderError
#当disposition是inline时,页面中将打印hello world,如果是attachment,那么文件将被下载为a.txt
send_data("hello world", disposition: "inline", filename: "a.txt",type:"plain/text")
42.通过rails plugin new plugin_name创建一个插件。
插件的test/dummy下有一个假的rails项目,可以用来定义controller和view供plugin测试使用。
当执行rake test时,
1.执行项目根目录下的RakeFile,该文件将检查gem是否全部install了,初始化rdoc的内容,并且告诉rake需要执行哪些test文件
t.pattern = 'test/**/*_test.rb'
2.rake知道需要执行哪些test文件后便会一个一个对测试文件进行初始化(将Test类放入运行队列中,这一步并没有实际的运行test),一般测试文件开头处都会require 'test_helper'。该文件会执行
test/dummy/config/environment.rb文件中的内容。
3.众所周知,environment.rb是一个rails项目的入口,他会调用application.rb,
application.rb会调用boot.rb,boot.rb的唯一使命就是负责将所有安装好的Gem加入到load_path里来,并且如下图第三行所示,将插件的lib目录加入到load_path
该步骤只会改变$:($LOAD_PATH),不会实际去require任何东西。执行完root.rb后,application.rb会require所有的外部依赖gem,并且require 插件名.rb,表示对插件进行初始化。
最后该文件会定义Application的具体细节
4.application.rb执行结束,又回到environment.rb,
该语句会把rails项目中得controller,helper,model等文件夹以及其子文件夹递归的加入到$LOAD_PATH中。
5.执行test
45.form表单元素
f.check_box :group_ids, {checked: true, multiple: true}, group.id