博客

model自定义属性的使用

by 小赓赓。 at almost 10 years ago, last updated at almost 10 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 10 years ago, last updated at over 9 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 10 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 10 years ago, last updated at almost 8 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 10 years ago, last updated at almost 10 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