博客

model自定义属性的使用

by 小赓赓。 at almost 8 years ago, last updated at almost 8 years ago
W

如果在一个model中想使用另一个model中的属性,可以自定义.比如博客model中如果想使用标签,而标签是属于tags这个model,就可以使用自定义属性.只需两步:

1.在博客的model中定义方法

def tags_string= one_tags
    one_tags.split(',').each do |tag|
      one_tag = Tag.find_by(title: tag)
      one_tag = Tag.new(title: tag) unless one_tag
      self.tags << one_tag        
    end
  end

2.在view中使用,如使用input标签的话,可以利用其name和value属性赋值,在我们controller的new之后,通过key-value的形式,从而将value中的内容作为参数传递给model中的def方法

<div class="form-group">
  <input type="text" name="blog[tags_string]" value="<%= @blog.tags.map(&:title).join(',')%>"></input><small>(标签用逗号分隔)</small>
</div>

以上是我们将数据库中没有的属性进行自定义,当然也可以对已经拥有的属性或者说原生的属性再次定义,也就是重定义,这样做实际就是覆盖了数据库中这个属性,用attr_accessor,write_attribute等关键字:

class Blog < ActiveRecord::Base
  def content= one_content
    write_attribute :content, one_content * 2
  end
end

同时如果想使用一些gem包来作为一些属性也可以自定义,如:想把标题的汉字转化为拼音的形式,在引入gem包gem 'chinese_pinyin'之后同样可以定义:

class Blog < ActiveRecord::Base
  def title_pinyin
    Pinyin.t self.title
  end
end

CRUD中的一些查询

by 小赓赓。 at almost 8 years ago, last updated at almost 8 years ago
W

n+1查询

有时查询一条数据时会关联许多数据,会导致内部查询很多很多次,所带来的坏处可想而知,主要就是查询时间过长.解决方法就是使用includes(表名)

find vs find_by

1.find 只能查询用户id.下面可以看出两种都可以同查询出数据,但是如果要查询数据库中没有的数据时,使用find_by则会返回一个nil,而find方法则会抛出异常

2.2.3 :001 > u = User.find 1
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

2.2.3 :005 > u = User.find_by id:1
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

2.find_by可以查询任何的数据通过key-value的形式

2.2.3 :007 > u = User.find_by username: "wu"
  User Load (0.8ms)  SELECT  `users`.* FROM `users` WHERE `users`.`username` = 'wu' LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

根据这两点酌情使用

find_by!

! 在ruby中大多是修改数据自身.而在rails不太一样.如在rails console中查询一个不存在的数据,使用find_by!时就会抛出异常,需要我们手动抓取异常

find_by_sql

这个是让我们用原生的sql语句去查询数据的如:

2.2.3 :009 > u = User.find_by_sql "select * from users"
  User Load (0.6ms)  select * from users
 => [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">, #<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]
#  可以看出其实是把数据封装成一个数组,所以也可以用下面的方式查询
2.2.3 :010 > u.first.id
 => 1 

用于非常复杂的数据查询,但有可能会有sql注入的不安全隐患.另外,我们使用这种方式查询时,model和user或者其他的表没有对应关系,也就是可以查询其他随意一张表,但会把其封装成此model的对象.还有如果出现同名表的情况,那只能访问从前往后的第一个,后面访问不到(as:声明别名).

where

类似嵌入一些ruby的语法去查询,如:

# 使用数组
2.2.3 :011 > u = User.where(["id = ?",2])
  User Load (1.0ms)  SELECT `users`.* FROM `users` WHERE (id = 2)
 => #<ActiveRecord::Relation [#<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]> 
# 使用hash
2.2.3 :012 > u = User.where(id:2)
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2
 => #<ActiveRecord::Relation [#<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]> 

where其实是把查询的数据封装成一个对象,但是在我们没有使用each,to_a等方法之前他并没有将操作传递给数据库,所以我们可以一直利用这个对象继续查询,他会把所有查询过的数据全部封装为一个对象

2.2.3 :019 > w = User.where(id:1)
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
 => #<ActiveRecord::Relation [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">]> 

2.2.3 :021 > w = w.where(username: "wu")
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`username` = 'wu'
 => #<ActiveRecord::Relation [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">]> 

对Rails路由的简单认识

by zy at almost 8 years ago, last updated at almost 8 years ago
R

Rails 路由的基本功能

  • 接受并识别http请求,将请求对应到相关的controller和action

  • 处理url附加的参数

  • 识别link_to 和redirect_to

路由的分类

  • 一般路由
get '/users/:id', to: 'users#show'
  • 命名路由
get '/patients/:id', to: 'patients#show', as 'user'
  • 资源路由
resources :users do
  member do
    get 'preview'
  end
  collection do
    get 'recent'
  end
end

通过 rake routes 命令查看生成对应的资源路由,其实 常用的一般都是资源路由。

资源路由可以在内部自定义成员路由,关键字(member),需要传递资源id.

和集合路由,关键字(collection),不需要传递资源id.

Http Status Code In Rails

by 小赓赓。 at almost 8 years ago, last updated at almost 8 years ago
W

Http状态码用以表示网页服务器http响应状态的3位字符代码.

1xx系列(临时响应):

代表请求已被接受,需要继续处理.这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束.如

100:(:continue)初始的请求已经接受,客户应当继续发送请求的其余部分.

2xx系列(成功):

代表请求已成功被服务器接收,理解,并接受如:

200(:ok):服务器已成功处理了请求.通常,这表示服务器提供了请求的网页.

3xx系列(重定向):

这类状态码代表需要客户端采取进一步的操作才能完成请求.通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的 Location 域中指明.最好不要超过5次.如

300(:multiple_choices):针对请求,服务器可执行多种操作.客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出.如果服务器要提出优先选择,则应该在Location应答头指明.

301(:moved_permanently):请求的网页已永久移动到新位置.并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一.

304(:not_modified):如果网页自请求者上次请求后再也没有更改过,您应将服务器配置为返回此响应(称为 If-Modified-Since HTTP 标头)。服务器可以告诉 爬虫自从上次抓取后网页没有变更,进而节省带宽和开销.

4xx(请求错误)系列:

表示客户端的差错,如请求中有错误的语法或不能完成.这些状态码表示请求可能出错,妨碍了服务器的处理.如:

400(:bad_request):服务器不理解请求的语法.

401(:unauthorized):客户试图未经授权访问受密码保护的页面.

403(:forbidden):资源不可用.服务器理解客户的请求,但拒绝处理它.通常由于服务器上文件或目录的权限设置导致.

404(:not_found):服务器找不到请求的网页.例如,对于服务器上不存在的网页经常会返回此代码.

5xx系列(服务器错误)

这些状态码表示服务器在处理请求时发生内部错误.这些错误可能是服务器本身的错误,而不是请求出错.

500(:internal_server_error):服务器遇到了意料不到的情况,不能完成客户的请求.

502(:bad_gateway):服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答.

301 && 302

301和302都是请求的网页转移到新位置,但是301的请求是将网页永久的转向新的位置,从而永久的替换之前的位置.也就是告诉爬虫以后请求的位置就永久的改为此,之前的作废.而302的请求是临时性的,就是此次请求位置变动,但之后的请求仍为原来的位置,一些搜索引擎的爬虫会继续抓取原有位置并编制索引. 如:做好了一个网站,但现在感觉比如单品的界面的url比较乱,想采用更直观的"/user/product"的方式,这时我们的状态码就应该使用301,因为需要废弃之前的url,永久的告诉爬虫此页面url改为此.

Request信息收集

by Mafeng at almost 8 years ago, last updated at almost 8 years ago
G

在Controller的Action之中,Rails提供了一些方法可以让你得知此request各种信息,包括:
action_name 目前的Action名称

  • cookies Cookie下述
  • headers HTTP标头
  • params 包含用户所有传进来的参数Hash,这是最常使用的信息
  • request 各种关于此request的详细信息
  • request_method
  • mime_type
  • content_type
  • headers
  • body
  • content_length

“ params ” 这个Hash是ActiveSupport::HashWithIndifferentAccess对象,而不是普通的Hash而已。Ruby内建的Hash,用Symbol的hash[:foo]和用字符串的hash["foo"]是不一样的,这在混用的时候常常搞错而取不到值,Rails在这里使用的ActiveSupport::HashWithIndifferentAccess对象,无论键是Symbol或字符串,都指涉相同的值,减少麻烦。

before_filter

by Mafeng at almost 8 years ago, last updated at almost 8 years ago
G

before_filter最常用于准备跨Action共享的数据,或是用户权力验证等.

class EventsControler < ApplicationController
  before_filter :find_event, :only => :show
  def show
  end
  protected
  def find_event
    @event = Event.find(params[:id])
  end
end

Filter的顺序:
1. 当有多个Filter时,Rails是由上往下依序执行的。如果需要加到第一个执行,可以使用prepend_before_filter方法,同理也有prepend_after_filter和prepend_around_filter.
2. 如果需要取消从父类别继承过来的Filter,可以使用skip_before_filter :filter_method_name方法,同理也有skip_after_filter和skip_around_filter。

Render 小结

by 小赓赓。 at almost 8 years ago, last updated at almost 8 years ago
W

render的意思就是渲染,渲染视图.在浏览器的request之后作出相应的response,然后把相应的视图渲染到此视图中.他的主要作用范围有两个:在controller中和在views中使用.

1.在controller中

修改action查找view的行为,使想要呈现的视图显示出来.如

def new

  end

  def create
    @user = User.find_by(username: params[:username],password: params[:password])
    if @user 
      session[:user_id] = @user.id
      flash[:notice] = "登录成功"
      redirect_to root_path
    else
      flash[:notice] = "用户名或密码不正确"
      render action: :new
    end
  end
#此代码的作用是如果用户名或密码不正确,重新渲染此页面并显示错误信息

render后可以跟的行为有很多:如

  render text: 'ok'
  render json: @users
  render xml: @users
  render file: 'app/views/users/index'
  render partial: 'app/views/users/search'

Pay attention

一个action只能执行一次render或redirect_to

def search
  if @user
    render json :@user
    return  #如果此处不加return相当与执行了两次render会出现异常
  end
  render text: "OK"    
end

2.在views中

可以渲染子视图,并且能够访问当前view或者action的所有实例变量.

# app/views/users/index.html.erb

# app/views/shared/_menu.html.erb
<%= render "shared/menu" %>
# 这样就可以渲染出/app/views/shared/_menu.html.erb中的视图
<h1>Products</h1>
<p>Here are a few of our users:</p>
...

render同样可以传递参数:

<% @user.each do |user| %>
  <%= render partial: "one_user", locals: {user: user} %>
# locals中可以看作key-value的形式,把当前each中的参数user传到partial中的user中
<% end -%>
# or
<%= render "one_user", collection: @users, as: :user %>
#或者直接把@users实例直接传递给partial中的user

sessions && cookies

by 小赓赓。 at almost 8 years ago, last updated at almost 8 years ago
W

sessions和cookie实际是两个概念:

sessions是后端实现的,服务器端实际利用sessions机制保留了对当前用户的访问的方法或识别.利用cookie来追踪,sessions会针对每一个用户生成一个key进行追踪,key会存储在cookie中,每次用户返回给服务器信息时,后端使用后端机制取出key,然后通过这个key取出信息.

cookies是基于浏览器端的实现,与服务器之间通过response和request对信息进行传递.

sessions VS cookies

  • sessions存储后端的数据结构,如对象
  • cookies只支持字符串

  • sessions没有大小限制;因为也是基于cookie存储的,所以也并不建议存储一些庞大的数据.也不利于相互交互的效率;

  • cookies有大小限制

  • 因为cookie存在与浏览器端,所以其实可以分析出你的cookie.重要信息最好放在session中,如用户登录信息.

Module基础:MysqL数据库使用

by 小赓赓。 at almost 8 years ago, last updated at almost 6 years ago
W

1.在创建的rails项目下首先确定是否安装有Mysql:

#可以通过whereis mysql查看路径,如果没有,安装
 gem install mysql2

2.会发现报错,因为缺少相关必要的libraries:

 sudo apt-get install libmysql-ruby libmysqlclient-dev

需要注意的是 ubuntu14.04以后libmysql-ruby 更名为 ruby-mysql 3.新终端打开Mysql并登陆:

 sudo /etc/init.d/mysql start
 mysql -uroot -p

4.在项目的Gemfile中修改:gem 'mysql2'

5.在database.yml中进行相关的配置(ps;这是一种数据序列化(serialization )语言,是一种可读的文本的数据结构,它的设计目标是使人们容易读,程序容易处理。它类似XML,但是比XML简单)例如

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  host: 127.0.0.1
  username: root
  password:

development:
  <<: *default
  database: circles_development

test:
  <<: *default
  database: circles_test

production:
  <<: *default
  host: 127.0.0.1
  database: circles_production
  username: circles
  password: circles_p_roduction

6.接下来创建一个module:

rails g model user

7.然后就可以使用rake创建一张表,并移植到rails中如:

rake db : create
rake db : migrate

8.此时我们已经连接到数据库并创建了表,现在我们可以进行数据的增删改查了,在rails中最大的便捷之处就是不用一句一句的写sql语句,rails有内置的机制可以方便的进行操作,命令就是:

rails console

mysql的安装与rails配置修改

by Mafeng at almost 8 years ago, last updated at almost 8 years ago
G

mysql的安装与rails配置修改

mysql的安装
Ctrl+alt+T 打开终端 输入命令:

sudp apt-get update
sudo apt-get install mysql-server
sudo apt-get install mysql-client
sudo apt-get install libmysqlclient-dev

ps:注意本地开发密码设置为空

安装完成之后可以通过

sudo /etc/init.d/mysql start      #启用mysql服务
mysql -u root -p              #以root用户登录

在这里mysql已经配置完全,可以使用了。

rails的配置

  • 在没有设置的情况下,rails 的默认数据库使用的是自带的sqlite3,当我们需要更换数据库时,要在项目中的Gemfile文件进行修改,在Gemfile中找到“gem ‘sqlite3’ ”修改为所要更换的数据库名,在这里修改为“ gem ‘mysql2’ ”,如要使用其他数据库自行查找。
  • 修改config/locales/databases.yml文件,原文件:
default: &default
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3

修改后的文件(项目名为circles) :

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  host: 127.0.0.1
  username: root
  password:

development:
  <<: *default
  database: circles_development
test:
  <<: *default
  database: circles_test
production:
  <<: *default
  host: 127.0.0.1
  database: circles_production
  username: circles
  password: circles_p_roduction

至此rails配置完成,打开终端在项目路径下运行 rake db:create,这样就完成了rails支持mysql的操作

博客总数:59