创建或修改目录:/www/wwwroot/104.219.215.234/data 失败!
badnews 国产 入手执行:Oracle 和 Ruby on Rails - 第四色

你的位置:第四色 > 小电影网站 >

badnews 国产 入手执行:Oracle 和 Ruby on Rails

发布日期:2024-11-03 13:19    点击次数:83
Oracle 时间网 结合使用 Oracle 和 Ruby on Rails 认识

本教程先容若何使用 Oracle 装配 Ruby/Railsbadnews 国产,以及若何设备高效且功能刚毅的 Ruby/Rails 应用方法。您将获取为企业创建刚毅的 Ruby/Rails 应用方法所需的学问。

所需时间

大要 1 个小时

概括

Ruby on Rails 是一个免费的 Web 应用方法框架,旨在使咱们冒昧愈加速捷地创建数据库驱动的 Web 站点,并从一运行就提供主要代码框架(结构)。Ruby on Rails 继续缩写为 Rails 或 RoR,它是一个用 Ruby 编程说话编写的开源名目,使用 Rails 框架的应用方法是用模子-视图-收敛器计算模式设备的。

RoR 在 J2EE 和 PHP 编程东谈主员中备受珍摄。当您了解 RoR 的上风后,它对 J2EE 和 PHP 编程东谈主员的眩惑力具有进击作用。最初,它使用任何炫耀自大的计算模式都很钦佩的严格的模子-视图-收敛器体绑缚构 — 这不错讲解它为什么眩惑了多数 J2EE 设备东谈主员。其次,使用 Rails 不错节略地构建基本系统 — 这对 PHP 设备东谈主员具有眩惑力。

RoR 为 MVC 提供了令东谈主闲隙的处置决策。模子不单是是数据;它践诺适用于该数据的悉数业务礼貌。模子既可充任网关守卫又可充任数据存储。视图继续基于模子中的数据生成一个用户界面。尽管视图可能通晓过各式款式向用户败露输入的数据,但视图自己从不处理传入的数据。数据败露之后,视图的职责就完成了。收敛器接受来自外界的事件(继续是用户输入),与模子进行交互,并向用户败露相应的视图。

RoR 将 ActiveRecord 算作对象关系映射 (ORM) 层提供,以便同一数据库和操作数据。ActiveRecord 严格撤职标准的 ORM 模子:表映射到类,行映射到对象,列映射到对象属性。

创建 Rails 应用方法时,将在根目次下生成以下目次和文献:app、components、config、db、doc、lib、log、public、Rakefile、README、script、test、tmp 和 vendor。

Ruby 是一种动态的开源编程说话,要点边幅浅陋性和工积恶果。其粗略的语法易于阅读、便于编写。要了解关系 Ruby 说话的更多信息,参见附录:Ruby 初学。

要获取更多信息,您不错看望 Ruby on Rails OTN 论坛。

创建同一

您将在本节中使用以下号召:

OCI8.new (userid, password, dbname = nil, privilege = nil):

通过 userid 和 password 同一到 Oracle。dbname 是 Net8 的同一字符串。要是您需要 DBA 权限,则将 privilege 竖立为 :SYSDBA 或 :SYSOPER。

 

OCI8#logoff

断开与 Oracle 的同一。将回滚未提交的事务。

OCIError 包含 Oracle 的舛错代码的颠倒类。您不错通过 OCIError#message 获取舛错音信,通过 OCIError#code 获取舛错代码。

创建 ruby 剧本流程中的第一个任务是创建到数据库的同一。践诺以下智商:

.

在末端窗口中,通过践诺以下号召来践诺 connect.rb 剧本:

export NLS_LANG=American_America.UTF8
ruby connect.rb

要是同一顺利,您会看到上头的音信;要是同一失败,您将看到一条舛错音信。

connect.rb 文献的本色如下:

# connect.rb: Create connections to Oraclerequire 'config.rb'
begin	# login as normal user	conn1 = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)	puts "login as normal user succeeded."	conn1.logoff	puts "logoff succeeded."		puts
	# login as DBA	conn2 = OCI8.new('sys', 'oracle', DB_SERVER, :SYSDBA)	puts "login with DBA privilege succeeded."	conn2.logoff	puts "logoff succeeded."
rescue OCIError	# display the error message	puts "OCIError occured!"	puts "Code: " + $!.code.to_s	puts "Desc: " + $!.message
end
puts '-'*80
av女优的现场

 

.

本教程的其余剧本中将包括以下号召:

require 'config.rb'  #create connection conn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# operations on conn goes here

 #log out conn.logoff

 

查询数据

您将在本节中使用以下号召:

OCI8#parse (sql)

创建一个游标,准备践诺 SQL 语句并复返 OCI8::Cursor 的实例。

OCI8#exec (sql, *bindvars)

践诺 SQL 语句。复返值的类型取决于 SQL 语句的类型。指定 bindvars 后,它们在践诺前算作绑定变量进行绑定。

OCI8::Cursor#exec(*bindvars) 践诺用游标分派的 SQL 语句。复返值的类型取决于 SQL 语句的类型。 OCI8::Cursor#getColNames 将选拔列表的称号算作数组获取。在践诺后使用此方法。

要创建一个浅陋查询并败露阻隔,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 fetch.rb 剧本:

ruby fetch.rb

其输出败露在屏幕截图中。

fetch.rb 文献的本色如下:

#fetch.rb: Fetch data from databaserequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# parse and exec the statementcursor = conn.parse("select * from regions")cursor.exec
# output column namesputs cursor.getColNames.join(",")
# output rowswhile r = cursor.fetch 	puts r.join(",")end
# close the cursor and logoffcursor.closeconn.logoffputs '-'*80

 

.

还不错通过另一种款式编写更针关于 ruby 的相通的代码。在末端窗口中,通过践诺以下号召来践诺 fetch_r.rb 剧本:

ruby fetch_r.rb
The output is shown in the screenshot. 

fetch_r.rb 文献的本色如下:

# fetch_r.rb: Fetch in a more ruby-like wayrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# Fetch and display the rows in a blocknrow = conn.exec("select * from regions") do |r|	puts r.join(",")end
# Display count of rowsputs ' '*30 + nrow.to_s + " rows were fetched."
conn.logoffputs '-'*80

 

.

在获取好多行时,事前获取有助于改善性能。在末端窗口中,通过践诺以下号召来践诺 prefetch.rb 剧本:

ruby prefetch.rb
The output is shown in the screenshot. 

prefetch.rb 文献的本色如下:

# prefetch.rb: Prefetch datarequire 'config.rb'
SELECT_STATEMENT = "select a.first_name, a.last_name, b.first_name, b.last_name,
   a.salary - b.salary salarydiff 
from employees a, employees b 
where b.id > a.id"
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# Execute statement with different prefetch sizes[nil,100].each do |prefetchrows|
  cursor = conn.parse(SELECT_STATEMENT)
  if prefetchrows    cursor.prefetch_rows = prefetchrows  else    prefetchrows = "default"  end
  puts "Executing with prefetch rows = #{prefetchrows}"
  time1 = Time.now
  cursor.exec
  while r = cursor.fetch()    # puts r.join(",")  end
  # Display count of rows  puts ' '*30 + cursor.row_count.to_s + " rows were fetched."
  time2 = Time.now  puts "Time cost: " + (time2-time1).to_s  puts
end
conn.logoffputs '-'*80

 

绑定变量

绑定变量晋升了代码可重用性,摒除了 SQL 注入袭击的风险。您将在本节中使用以下号召:

OCI8::Cursor#bind_param(key, val, type = nil, length = nil)

显式绑定变量。当 key 为数字时,它通过位置绑定(从 1 运行)。当 key 为字符串时,它通过占位符称号绑定。

OCI8#exec (sql, *bindvars) or OCI8::Cursor#exec(*bindvars)

也不错通过 bindvars 绑定变量。

OCI8::Cursor#[key] 获取/竖立绑定变量的值。

要在本示例中使用绑定变量,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 bind.rb 剧本:

ruby bind.rb

其输出败露在屏幕截图中。

bind.rb 文献的本色如下:

# bind.rb: How to bind variablesrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# Prepare the data, also display what's hard-coded statementconn.exec("DELETE FROM test_bind")conn.exec("INSERT INTO test_bind VALUES(1, 'Unknown')")conn.exec("INSERT INTO test_bind VALUES(2, 'Unknown')")conn.exec("INSERT INTO test_bind VALUES(3, 'Unknown')")
# Now update the data using bind variables.cursor = conn.parse("UPDATE test_bind SET name = :name WHERE id = :id")cursor.bind_param(1,nil,String,100) #  Or: cursor.bind_param(1, ' '*100)cursor.bind_param(2,Fixnum)					#  Or: cursor.bind_param(2, id) 
id = 1['China', 'Korea', 'Japan'].each { |country|	cursor[1] = country	cursor[2] = id	cursor.exec	id = id + 1}
# Fetch back the updated dataconn.exec("SELECT * FROM test_bind").fetch do |row|	puts row.join(',')end
conn.logoff
puts '-'*80

 

.

要使用绑定变量测试性能改善,通过践诺以下号召来践诺 bind_perf_test.rb 剧本:

ruby bind_perf_test.rb
The output is shown in the screenshot. 

bind_perf_test.rb 文献的本色如下:

# bind_perf_test.rb: Performance test for binding variablesrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
# Not using bind varables.puts "Fetching result, not using bind variables:"time1 = Time.now(100..200).each { |id|	cursor = conn.parse("SELECT first_name FROM employees WHERE id = #{id}")  cursor.exec	#puts id.to_s + " --> " + cursor.fetch[0]}time2 = Time.nowputs "Time cost: " + (time2-time1).to_sputs
# Using bind varables.puts "Fetching result, using bind variables:"
time1 = Time.nowcursor = conn.parse("SELECT first_name FROM employees WHERE id = :id")cursor.bind_param(1, Fixnum)
(100..200).each { |id|    	cursor[1] = id	cursor.exec	#puts id.to_s + " --> " + cursor.fetch[0]}time2 = Time.nowputs "Time cost: " + (time2-time1).to_s
# End of the testconn.logoff
puts '-'*80

 

界说数据类型

您将在本节中使用以下号召:

OCI8::Cursor#define(pos, type, length = nil)

在分析和践诺流程中使用该方法。pos 从 1 运行。当 type 为 String 时使用 length。

您不错显式指明获取的值的数据类型。要在本示例中界说数据类型,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 define.rb 剧本:

ruby define.rb

其输出败露在屏幕截图中。

您会看到两个输出块之间的永逝。

define.rb 文献的本色如下:

# define.rb: Define output columns
require 'config.rb'


# Create a connection to Oracle
conn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)


# Prepare the data
conn.exec("DELETE FROM test_define");
conn.exec("INSERT INTO test_define VALUES(1,'Scott Tiger', SYSDATE, SYSTIMESTAMP)")

# Define to fetch Date and Time
cursor = conn.parse("SELECT name,birthdate,lastvisit FROM test_define WHERE id = :id")
cursor.bind_param(1, 1)
cursor.define(1, String, 100)
cursor.define(2, Date)
cursor.define(3, Time)
cursor.exec

while r = cursor.fetch
	puts r.join("\n")
end

puts 

# Define to fetch Date and Time as String
#conn.exec("ALTER SESSION SET nls_territory='TAIWAN' nls_language='TRADITIONAL CHINESE'")
cursor = conn.parse("SELECT name,birthdate,lastvisit FROM test_define WHERE id = :id")
cursor.bind_param(1, 1)
cursor.define(1, String, 100)
cursor.define(2, String, 100)
cursor.define(3, String, 100)
cursor.exec

while r = cursor.fetch
	puts r.join("\n")
end

conn.logoff
puts '-'*80

 

顾问事务

在 Oracle 数据库中操作数据(插入、更新或删除数据)时,篡改的数据或新数据在提交到数据库中之前仅在数据库会话中可用。篡改的数据提交至数据库,然后可供其他用户和会话使用。这是一个数据库事务。 单独提交每个篡改会额外加多劳动器的负载。继续,您但愿提交所特殊据或者什么都不提交。进行您我方的事务收敛具有性能和数据齐备性上风。 您将在本节中使用以下号召:

OCI8#autocommit

获取/竖立自动提交模式的现象。默许值是 false(记取:刊出时不回滚未提交的事务)。要是为 true,每次践诺 insert/update/delete 语句时都自动提交事务。

OCI8#commit() 提交事务。 OCI8#rollback() 回滚事务。

要了解若何顾问事务,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 transaction.rb 剧本:

ruby transaction.rb

该剧本使用 conn1 同一更新一瞥。在 Oracle 中,新数据在提交前仅在原始数据库会话中可见。其输出败露在屏幕截图中。

在这种情况下,conn2 同一不知谈 conn1 的未提交事务发生了什么。

transaction.rb 文献的本色如下:

# transaction.rb: How to use transactionsrequire 'config.rb'
# Create connections to Oracleconn1 = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)conn2 = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
conn1.exec("DELETE FROM test_transaction")conn1.exec("INSERT INTO test_transaction VALUES(1, 'old value')")conn1.commit
#conn1.autocommit = trueputs "OCI8.autocommit = " + conn1.autocommit.to_sputs "conn1 updated the name to 'something new'";conn1.exec("UPDATE test_transaction SET name = 'something new' WHERE id = 1");#conn1.commit
puts "conn2 got the name as '" + 		conn2.exec('SELECT name FROM test_transaction WHERE id = 1').fetch[0] + "'"
conn1.logoffconn2.logoff
puts '-'*80

 

.

更新 transaction.rb 剧本,取消对 conn1.autocommit = true 的扫视,然后保存文献。

使用以下号召再次践诺剧本:

ruby transaction.rb

当今,conn2 知谈哪些本色是新增的。其输出败露在屏幕截图中。

 

.

单独提交每一瞥会额外加多劳动器的负载。您不错比拟单独提交每行与在事务扫尾后提交之间的性能各异。要测试永逝,使用以下号召践诺 trans_perf_test.rb 剧本:

ruby trans_perf_test.rb

瞩目,第二个数字比第一个数字小。其输出败露在屏幕截图中。

trans_perf_test.rb 文献的本色如下:

# trans_perf_test.rb: Performance test for transactionsrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)conn.exec("DELETE FROM test_transaction")conn.commit
# Commit on each timeconn.autocommit = truetime1 = Time.now300.times{	conn.exec("INSERT INTO test_transaction VALUES(1, 'something')")}time2 = Time.now
# Commit on the last stepconn.autocommit = false	# It's the defaulttime3 = Time.now300.times{	conn.exec("INSERT INTO test_transaction VALUES(1, 'something')")}conn.committime4 = Time.now
# Output the comparationputs "Time cost of each-time commit(sec): " + (time2-time1).to_sputs "Time cost of one-time commit(sec) : " + (time4-time3).to_s
conn.logoff
puts '-'*80

 

使用 PL/SQL

PL/SQL 是 Oracle 对 SQL 的流程说话膨胀。PL/SQL 存储流程和函数存储在数据库中,因此其看望速率极度快。使用 PL/SQL 存储流程允许所特殊据库应用方法重用逻辑,无论应用方法以何种款式看望数据库。好多与数据联系的操作在 PL/SQL 中的践诺速率比将数据索要到一个方法中(举例,Ruby)然后再进行处理的速率快。

您将在本节中使用以下号召:

DBMS_UTILITY 和 DBMS_OUTPUT

Oracle 存储方法包。TO_CHAR 是一个内置函数。

要在 Ruby 剧本中调用 PL/SQL 流程和函数,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 plsql.rb 剧本:

ruby plsql.rb

其输出败露在屏幕截图中。

plsql.rb 文献的本色如下:

# plsql.rb: Call PL/SQL procedures and functionsrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
puts 'Get version information from Oracle:'cursor = conn.parse("BEGIN DBMS_UTILITY.db_version(:ver, :comp); END;")cursor.exec(' '*50,' '*50)puts "Oracle DB Version: " + cursor[1]puts "Oracle DB Compatibility: " + cursor[2]puts
puts 'Call TO_CHAR function:'cursor = conn.parse("BEGIN :str := TO_CHAR(:num, 'FM0999'); END;")cursor.exec('ABCD', 123)puts "TO_CHAR input: " + cursor[2].to_sputs "TO_CHAR output: " + cursor[1]puts
puts 'Get DBMS_OUTPUT:'conn.exec("BEGIN DBMS_OUTPUT.ENABLE(NULL); END;")conn.exec("BEGIN DBMS_OUTPUT.put_line('Hello world!'); END;")conn.exec("BEGIN DBMS_OUTPUT.put_line('Can you see me?'); END;")
cursor = conn.parse("BEGIN DBMS_OUTPUT.get_line(:line, :status); END;")cursor.bind_param(':line', nil, String, 255)cursor.bind_param(':status',Fixnum)
while true	cursor.exec	break if cursor[':status'] == 1	puts cursor[':line']end
puts '-'*80

 

使用 LOB:存储/检索图像

Oracle 字符大对象 (CLOB) 和二进制大对象 (BLOB) 列(以及 PL/SQL 变量)不错包含大容量 (GB) 的字符和二进制数据。您将在本节中使用以下号召:

OCI8::BLOB#available

查验 BLOB 是否可用。要使用 BLOB,您最初需要插入 EMPTY_BLOB()。

OCI8::BLOB#read(size = nil) 从 BLOB 读取最大的字节大小,要是大小不详,则读取到文献扫尾处。 OCI8::BLOB#write(string) 将给定的字符串写入到 BLOB。

要创建一个微型应用方法以将图像加载并败露到数据库,践诺以下智商。

.

剧本文献场地的文献夹中有一个 PNG 文献。创建一个名为 download 的文献夹。在末端窗口中,通过践诺以下号召来践诺 blob.rb 剧本:

mkdir downloadruby blob.rb

其输出败露在屏幕截图中。

blob.rb 文献的本色如下:

#blob.rb: Save and Load BLOBrequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
conn.exec("DELETE FROM test_blob")
# Must insert a EMPTY_BLOB before save real datacursor = conn.parse("INSERT INTO test_blob VALUES(:name, EMPTY_BLOB())")Dir["*.png"].each do |fname|	cursor.exec(fname)end
# Save BLOB into Oracleconn.exec("SELECT name,image FROM test_blob") do |name, image|	puts "uploading file: " + name	File.open(name, 'r') do |f|		image.write(f.read)		image.size = f.pos	endend
# Load BLOB from Oracleconn.exec("SELECT name,image FROM test_blob") do |name, image|	puts "downloading file: " + name	File.open("download/"+name, 'w') do |f|		f.write(image.read)	endend
# Endconn.logoffputs '-'*80

 

.

检讨 ruby.png 文献的权限。践诺以下号召:

ls -l ruby.png download/ruby.png

 

使用 XML

悉数版块的 Oracle 数据库都包含“XML DB”。此历练包括将 XML 数据从 Oracle 复返至 Ruby 的基本操作。您将在本节中使用以下号召:

DBMS_XMLGEN.getxml (statement)

字据 SELECT 语句从关悉数据生成 XML。它复返 CLOB。

要了解 Oracle 的基本 XML 功能,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 xml.rb 剧本:

ruby xml.rb

其输出败露在屏幕截图中。

xml.rb 文献的本色如下:

# xml.rb: Generate a xml document based on relational datarequire 'config.rb'
# Create a connection to Oracleconn = OCI8.new(DB_USER, DB_PASSWORD, DB_SERVER)
sql = "SELECT DBMS_XMLGEN.getxml('		SELECT dept.name,dept.id,		CURSOR(			SELECT emp.first_name,emp.last_name,emp.phone_number			FROM employees emp			WHERE emp.department_id=dept.id		) AS employees		FROM departments dept		WHERE dept.id in (20,110)'	) AS xml	FROM dual"
# Fetch as CLOBputs conn.exec(sql).fetch[0].read
conn.logoffputs '-'*80

 

使用 ActiveRecord

ActiveRecord 同一业务对象和数据库表以创建抓久的域模子,其中的逻辑和数据位于一个包装中。它是对象关系映射 (ORM) 计算模式的一个完好意思。要在本示例中使用 ActiveRecord,践诺以下智商。

.

在末端窗口中,通过践诺以下号召来践诺 activerecord.rb 剧本:

ruby activerecord.rb

其输出败露在屏幕截图中。

activerecord.rb 文献的本色如下:

# activerecord.rb: Using ActiveRecord, the ORM modulerequire 'config.rb'require 'rubygems'require 'active_record'
# Establish a connection to OracleActiveRecord::Base.establish_connection(	:adapter => "oracle_enhanced",	:database => DB_SERVER,	:username => DB_USER,	:password => DB_PASSWORD )
# Define the Classes, they are mapped to table countries and regionsclass Country < ActiveRecord::Base	belongs_to :regionendclass Region < ActiveRecord::Base	has_many :countriesend
# Enjoy the automatic Object-Relation Mappingcty = Country.find('CN')puts 'CN refers to [' + cty.name + ']'puts '[' + cty.name + '] is in [' + cty.region.name + ']'puts
rgn = Region.find(cty.region.id)puts 'Countries in the same region with [' + cty.name + ']'rgn.countries.each { |country| puts ' - ' + country.name }
puts '-'*80

 

使用迁徙和结构构建 Ruby on Rails 应用方法

在本教程的其余部分,您将使用以下术语:

Rake 一个用于构建其他 Ruby 方法的 Ruby 方法。在 Rails 中,Rake 用于践诺一系列任务,如 db:migrate、db:schema:dump、db:schema:load、db:test:prepare 和 db:test:purge。它在作用域和认识方面与常见的 Linux 计算器具近似。 模子 一个 Ruby 类,代表您应用方法中的一个进击对象,通过 ActiveRecord 的 ORM 联贯到您的数据库表。 迁徙 设备东谈主员不错在 Ruby(而非数据形貌说话 (DDL))中创建、修改和删除其数据库对象。 结构 通过创建、裁剪、检讨和删除 ActiveRecord 类反应的条款,为您的数据提供一个浅陋接口。结构生成后,它将包含收敛器文献(笃定您应用方法的用户最终转向哪些页面)和视图文献(呈现应用方法用户将看到的页面)。

要使用迁徙和结构构建一个 Rails 应用方法,践诺以下智商。

.

您将创建一个名为 holapp 的极度基本的 Rails 应用方法。在末端窗口中践诺以下号召:

rails holappcd holappgedit config/database.yml

 

.

用以下本色替换 config/database.yml 文献中的 development 部分,然后保存并关闭该文献。

development:    adapter: oracle_enhanced    username: rubyhol    password: welcome    database: localhost/orcl

 

.

当今不错生成 comic 模子。在末端窗口中践诺以下号召:

ruby script/generate model comic

 

.

您思裁剪生成的剧本。在末端窗口中输入以下号召:

gedit db/migrate/*_create_comics.rb

 

.

用以下本色替换 self.up 部分,然后保存并关闭该文献。

  def self.up    create_table :comics do |t|          t.column :name,:string    t.column :description, :string    t.column :price, :float    end  end

 

.

当今不错对数据库迁徙进行 rake 操作,以生成策动表。在末端窗口中输入以下号召:

rake db:migrate

 

.

不错通过以下号召生成 comic 模子的结构

ruby script/generate scaffold --skip-migration comic name:string description:string price:float

 

.

Webrick 是用 Ruby 编写的 HTTP 劳动器库,它使用 servlet 膨胀其功能。使用以下号召启动 Webrick 劳动器:

ruby script/server

 

.

您不错检讨该应用方法。掀开一个浏览器窗口,输入以下 URL。单击 New Comic 创建一札记载,以确保该应用方法浩瀚运行。

:3000/comics

输入 comic 信息,然后单击 Create。

comic 创建顺利。单击 Back。

 

.

创建另一个 comic。选拔 New comic。

输入 comic 信息,然后单击 Create。

另一个 comic 创建顺利badnews 国产。单击 Back。

 

.

列出了这两个 comic。您还不错对第一个 comic 选拔 Edit 进行裁剪。

篡改任何信息后单击 Update。

更新了该 comic。单击 Back。

 

.

还可删除一个 comic。对其中一个 comic 选拔 Destroy。

单击 OK 阐述。

更新了该 comic。单击 Back。

 

.

住手剧本劳动器。在运行该劳动器的窗口中按 Control+c。

 

用 Ruby on Rails 竖立数据关系模子并构建应用方法

教程这一节将有助于您了解如安在 Rails 中竖立各式数据关系的模子并基于这些关系构建应用方法。为此,您将创建一个应用方法,该方法景仰一个 articles 和 authors 数据库。

创建作家和著作

最初您将创建一个应用方法,以便通过该方法输入作家和著作。此外,您还将篡改表单以便输入某篇著作时可败露含有作家的弹出列表并在 Listing 和 Show 页面中败露著作作家。该应用方法面前在表间是一双一的关系。践诺以下智商:

.

另外掀开一个末端窗口,践诺以下号召:

cd /badnews 国产home/rubyhol/holappsource /etc/bashrc

 

.

生成 author 模子的结构。在末端窗口中践诺以下号召:

ruby script/generate scaffold author name:string vocation:string

 

.

生成 article 模子的结构。在末端窗口中践诺以下号召:

ruby script/generate scaffold article title:string author_id:integer abstract:text

 

.

当今,您需要让 Rails 知谈 Article 模子和 Author 模子之间的关系。为此,需要对生成的模子剧本进行裁剪。在末端窗口中输入以下号召:

gedit app/models/author.rb

 

.

用以下本色替换文献的本色,然后保存并关闭该文献。

class Author < ActiveRecord::Base   has_one :articleend

 

.

您思裁剪生成的剧本。在末端窗口中输入以下号召:

gedit app/models/article.rb

 

.

用以下本色替换文献的本色,然后保存并关闭该文献。

class Article < ActiveRecord::Base   belongs_to :authorend

 

.

当今不错对数据库迁徙进行 rake 操作,以生成策动表。在末端窗口中输入以下号召:

rake db:migrate

 

.

在末端窗口中,通过践诺以下号召再次启动剧本劳动器:

script/server &

 

.

您不错检讨该应用方法。掀开浏览器窗口,输入以下 URL,然后选拔 New author。

:3000/authors

输入一位新作家,然后单击 Create。

该作家创建顺利。单击 Back。

 

.

您思再创建一位作家。选拔 New author。

输入一位新作家,然后单击 Create。

该作家创建顺利。单击 Back。

未必败露您添加的作家列表。

 

.

当今您思创建一些著作。输入以下 URL,然后选拔 New articles。

:3000/articles

在 Title 处输入一个标题,对 Author 指定 Julia Child,输入任何摘抄信息。然后单击 Create。

该著作创建顺利。

请瞩目,这里的 Author 为 0。这是因为 author_id 的值无效,阻隔是“Julia Child”形成了 0。鄙人一节中,您将革命 new 和 edit 表单,以便冒昧通过一个弹出列表按姓名选拔作家(该弹出列表败露姓名但在代码中复返 author_id)。

 

革命 Articles 表单和列表

您将对生成的表单进行革命,从而在创建著作时对 Author 域生成一个弹出列表。另外,您还将修改 listings 和 show 页面以便这些页面能正确败露作家。践诺以下智商:

.

在新的末端窗口中输入以下号召(因为您之前的窗口正在运行剧本/劳动器)。

cd holapp
gedit app/views/articles/new.html.erb

将底下这行:

<%= f.text_field :author_id %>

替换为

<%= f.collection_select(:author_id, Author.all, :id, :name) %>

该文献当今应如下所示。

 

.

对 articles 目次中的 edit.html.erb 文献践诺相通的操作。在末端窗口中输入以下号召:

gedit app/views/articles/edit.html.erb

 

.

将底下这行:

<%= f.text_field :author_id %>

替换为

<%= f.collection_select(:author_id, Author.all, :id, :name) %>

该文献当今应如下所示。

 

.

再次输入以下 URL。您会看到您在前边创建的著作出当今该列表中。选拔 Edit。

:3000/articles

瞩目,当今您可从一个选拔列表中选拔作家了。选拔 Julia Child。然后单击 Update。

该著作创建顺利。

瞩目这里的 Author: 1。此为 author_id 的值。您可将此值改为姓名。

 

.

底下将篡改 articles 目次中的 index.html.erb 文献。在末端窗口中输入以下号召:

gedit app/views/articles/index.html.erb

 

.

将底下这行:

<td><%=h article.author_id %></td>

替换为

<td><%=h article.author.name %></td>

该文献当今应如下所示。

 

.

对 articles 目次中的 edit.html.erb 文献践诺相通的操作。在末端窗口中输入以下号召:

gedit app/views/articles/show.html.erb

 

.

将底下这行:

<%=h article.author_id %>

替换为

<%=h article.author.name %>

该文献当今应如下所示。

 

.

再次输入以下 URL。您会看到此时该作家出当今列表中。选拔 Show。

:3000/articles

您当今可在 Show 模式下看到悉数信息。

 

允许一位作家撰写多篇著作

您但愿允许一位作家撰写多篇著作。这需要将 Authors 表和 Articles 表之间的关系改为一双多的关系。践诺以下智商:

.

为了指明这种关系,需要篡改 author.rb 文献。在末端窗口中输入以下号召:

gedit app/models/author.rb

 

.

将底下这行:

 has_one : article 

替换为

 has_many : articles 

 

.

再次输入以下 URL,然后选拔 New article。

:3000/articles

新建一个著作。对 Author 选拔 Julia Child,然后单击 Create。

该著作创建顺利。单击 Back。

两个著作同期败清晰来。

 

允好多位作家合撰一篇著作

您但愿允好多位作家合撰一篇著作。这需要将 Authors 表和 Articles 表之间的关系改为多对多的关系。践诺以下智商:

.

您需要在 authors.rb 文献中再次篡改该关系。在末端窗口中输入以下号召:

gedit app/models/author.rb

 

.

将底下这行:

 has_many :articles 

替换为

 has_and_belongs_to_many :articles 

 

.

另外还需要篡改 article.rb 文献。在末端窗口中输入以下号召:

gedit app/models/article.rb

 

.

将底下这行:

 belongs_to :author 

替换为

 has_and_belongs_to_many :authors 

 

.

当今需要创建 Authors 和 Articles 之间的一个联结表。在末端窗口中输入以下号召:

script/generate migration CreateArticlesAuthors

 

.

当今需要对刚创建的文献进行篡改以创建一个表来存储作家和著作。在末端窗口中输入以下号召:

gedit db/migrate/*_create_articles_authors.rb

 

.

将底下的本色:

def self.up
end
def self.down
end

替换为

def self.up
  create_table :articles_authors, :id => false do |t|
    t.integer :author_id
    t.integer :article_id
    t.timestamps
  end
end
 
def self.down
  drop_table :articles_authors
end

 

.

当今不错对数据库迁徙进行 rake 操作,以生成策动表。在末端窗口中输入以下号召:

rake db:migrate

 

.

再次输入以下 URL。瞩目此时出现了一个舛错。

:3000/articles

 

.

既然当今是多对多的关系,Article 模子就具著明为 authors 和 author_ids 的方法而不是名为 author 和 author_id 的方法。要矫正这个舛错,需要在 new.html.erb 文献中创建和裁剪弹出列表并败露您前边创建的用于处理多位作家的域。在末端窗口中输入以下号召:

gedit app/views/articles/new.html.erb

 

.

将底下这行:

<%= f.collection_select(:author_id, Author.all, :id, :name) %>

替换为

<%= f.collection_select(:author_ids, Author.all, :id, :name, {},
                        {:multiple => :multiple} ) %>

该文献当今应如下所示。

 

.

另外还需要篡改 articles 目次中的 edit.html.erb 文献。在末端窗口中输入以下号召:

gedit app/views/articles/edit.html.erb

 

.

将底下这行:

<%= f.collection_select(:author_id, Author.all, :id, :name) %>

替换为

<%= f.collection_select(:author_ids, Author.all, :id, :name, {},
                        {:multiple => :multiple} ) %>

该文献当今应如下所示。

 

.

还需要篡改 articles 目次中的 index.html.erb 文献。在末端窗口中输入以下号召:

gedit app/views/articles/index.html.erb

 

.

将底下这行:

<th>Author</th>

替换为

<th>Authors</th>

需要获取悉数作家的姓名并践诺 join 操作将它们同一在通盘。将底下这行:

<td><%=h article.author.name %></td>

替换为

<td><%=h article.authors.map {|auth| auth.name}.join(", ") %></td>

该文献当今应如下所示。

 

.

临了,篡改 articles 目次中的 show.html.erb 文献。在末端窗口中输入以下号召:

gedit app/views/articles/show.html.erb

 

.

将以下代码行:

<b>Author: </b>
<%=h article.author.name %>

替换为

<b>Authors: </b>
<%=h article.authors.map {|auth| auth.name}.join(", ") %>

该文献当今应如下所示。

 

.

再次输入以下 URL。瞩目列表中莫得败露任何作家。这是因为您切换了抒发式。您可能已矫正了这个问题,即已使用一个迁徙将 articles 表中的数据引入到了 articles_authors 表中。但这里咱们使用应用方法将作家添加转头。选拔 Boning a Duck 标题的 Edit 联贯。

:3000/articles

对 Author 选拔 Julia Child,然后单击 Update。瞩目这里的选拔列表允许您选拔多位作家而不是只选一位。

该著作更新顺利。单击 Back。

选拔 The Importance of Butter 标题的 Edit 联贯。

按下 Control 键的同期选拔这两位作家,单击 Update。

该著作更新顺利。单击 Back。

当今该著作败露不啻一位作家。

 

结合使用 AJAX 和 Ruby on Rails

使用 AJAX 是为了让浏览器端更智能,使其进展得果真就像“旧例的”应用方法。您的页面不错是交互式的,况且可从劳动器获取更新而无用刷新整个窗口。 举例,您可能会有一些著作,它们在运行时是正在进行的职责,随后您完成了它们。您但愿老是冒昧看到未完成著作的列表。将一篇著作绮丽为已完成后,您但愿更新该列表而无用刷新整个页面。 但在使用 AJAX 之前,运行时使用一个非 AJAX 的“unfinished”列表是最容易的。您需要更新数据库表以明确一篇著作是否已完成。著作运行时是未完成现象,将不错使用一个按钮来将它们绮丽为已完成。为了便于看望,您的页面布局中将有一个列表来败露悉数未完成的著作。践诺以下智商:

.

添加一个 boolean 类型的列 is_finished。在末端窗口中践诺以下号召:

script/generate migration AddIsFinishedToArticle is_finished:boolean

 

.

接着,需要将现存著作绮丽为未完成。在末端窗口中践诺以下号召:

gedit db/migrate/*_add_is_finished_to_article.rb

 

.

将以下行:

  add_column :articles, :is_finished, :boolean

篡改为

  add_column :articles, :is_finished, :boolean, :default => false
  Article.reset_column_information
  Article.find(:all).each do |a|
    a.is_finished = false
  end

 

.

当今您将更新数据库。在末端窗口中输入以下号召:

rake db:migrate

 

.

接着,您思添加一个“Mark Finished”按钮,使其调用新的 mark_finished 操作。在末端窗口中输入以下号召:

gedit app/views/articles/show.html.erb

 

.

在 <%= link_to 'Back', articles_path %> 行的背面添加底下一瞥。

<%= button_to "Mark Finished", :action => :mark_finished, :id  => @article.id %>

 

.

您需要更新页面布局以败露到未完成著作的联贯。应使此代码与主布局分离开来。您将生成一个新的“局部模板”,其文献名以字符“_”(下划线)起头以标明它不是一个齐备的模板。该模板将查找 is_finished 为 false 的著作并联贯到这些著作。在末端窗口中践诺以下号召:

gedit app/views/articles/_unfinished.html.erb

 

.

在该文献中添加以下代码:

  <div class="unfinished-title">Unfinished Articles</div>  <table>    <% for article in Article.all(:conditions => {:is_finished  => false}) %>     <tr> <%= link_to article.title, :action => :show, :id  => article.id %> </tr>    <% end %>  </table>

 

.

接着,需要在页面布局中援用这个新的“局部模板”以便悉数页面败露它。在末端窗口中践诺以下号召:

gedit app/views/layouts/articles.html.erb

 

.

紧随 <p style="color:green"><%= flash[:notice] %></p> 之后添加以下代码:

 <div id="unfinished">  <%= render(:partial => "unfinished") %> </div>

 

.

接着,需要编写新按钮将践诺的 mark_finished 操作的代码。在末端窗口中践诺以下号召:

gedit app/controllers/articles_controller.rb

 

.

向下鼎新至文献底部。在临了一个“end”的前边添加以下代码:

    # POST /articles/mark_finished/1    # POST /articles/mark_finished/1.xml    def mark_finished      @article = Article.find(params[:id])      @article.update_attribute(:is_finished, true)        respond_to do |format|        format.html { redirect_to(:action => :show) }        format.xml  { head :ok }      end    end  
          

 

.

您已更新了数据库,向页面布局添加了按钮和操作以及列表。当今可对该功能进行测试了。在浏览器中输入以下 URL:

    :3000/articles

瞩目页面顶部列出了未完成的著作。选拔 Boning a Duck 联贯。

单击 Mark Finished 按钮。

您会看到 Boning a Duck 已从 Unfinished Articles 列表中删除。选拔 Back。

 

.

此时您不错尝试 AJAX 了!您但愿将应用方法篡改成这么:当您按下该按钮时,窗口会自动更新而不会刷新整个屏幕。为此,您思让“Mark Finished”按钮发送一个 AJAX 号召来践诺 mark_finished 操作,然后再发还一个号召更新“Unfinished Articles”标题下的本色。最初将该按钮篡改为一个而已 (AJAX) 表单。在末端窗口中践诺以下号召:

  gedit app/views/articles/show.html.erb

 

.

将以下语句:

  <%= button_to "Mark Finished", :action => :mark_finished, :id  => @article.id %>

篡改为

  <% form_remote_tag :url => { :action => :mark_finished, :id  => @article } do %>   <%= submit_tag "Mark Finished" %>  <% end %>

 

.

当您按下该按钮时,应用方法将像畴昔相似进行更新,但不发送整个页面,您需要发送回某个 JavaScript 以便只更新未完成著作列表。通过使用一个而已 javascript 模板,Rails 可为您生成这个 JavaScript。在末端窗口中践诺以下号召新建一个文献:

  gedit app/views/articles/mark_finished.js.rjs

 

.

输入以下代码行:

  page.replace_html("unfinished" , :partial => "unfinished")

 

.

为使其奏效,在悉数页面中需有一些默许的 JavaScript 子例程。您需要裁剪布局。在末端窗口中践诺以下号召新建一个文献:

gedit app/views/layouts/articles.html.erb

 

.

在 <%= stylesheet_link_tag 'scaffold' %> 之后添加下行:

<%= javascript_include_tag :defaults %>

 

.

接着,需要更新 mark_finished 操作以使用新的而已模板,该模板与该操作同名。在末端窗口中践诺以下号召新建一个文献:

gedit app/controllers/articles_controller.rb

 

.

将以下代码:

    # POST /articles/mark_finished/1    # POST /articles/mark_finished/1.xml    def mark_finished      @article = Article.find(params[:id])      @article.update_attribute(:is_finished, true)        respond_to do |format|        format.html { redirect_to(:action => :show) }        format.xml  { head :ok }      end    end
          

篡改为

    # *AJAX* /articles/mark_finished/1    def mark_finished      @article = Article.find(params[:id])      @article.update_attribute(:is_finished, true)        respond_to do |format|        format.js      end    end

 

.

您已转为使用一个 AJAX 肯求表单并发还 Javascript 以更新列表。在浏览器中输入以下 URL:

    :3000/articles

新建一个著作。选拔 New article。

对 Title 输入 Gravity,对 Author 选拔 Julia Child,对 Abstract 输入 Gravity makes cakes fall,然后单击 Create。

您会看到 Unfinished Articles 列表中列出了 Gravity。选拔 Gravity 联贯。

单击 Mark Finished。

Gravity 立即从列表中灭亡。该页面未王人备刷新。这是 AJAX 的功劳。在像这么一个浅陋的屏幕上,使用和不使用 AJAX 之间的永逝可能不太彰着,因为您的 Web 劳动器发送的页面较小。但在含有图像、flash 和/或多数数据的更为复杂的屏幕上,其永逝不错是浩大的。要是使用 AJAX,则劳动器不错只发送有变化的部分。因此,您如实会玩赏 Rails 对 AJAX 相沿!

 

总结

在本教程中,您学习了若何:

通过 Oracle 装配 Ruby on Rails 创建 Oracle 数据库同一 查询数据 绑定变量 界说数据类型 创建并顾问事务 使用 PL/SQL 使用 LOB 存储和检索图像 使用 XML 使用 ActiveRecord 通过 Rails 欺诈迁徙和结构来创建应用方法 在 Rails 应用方法中处理各式表间关系 资源 -lang.org/ OTN 上的 Oracle Database 快捷版 “Ruby on Rails 之 Oracle 应用”常见问题解答 OTN 上的 Ruby/Ruby On Rails 论坛 附录:Ruby 初学

本教程的此部分给出了 Ruby 说话的概括。底下列出了您将碰到的对象。要是您熟识 Ruby,不错跳过这一部分,赓续下一步的学习。

$var # 全局变量 @var  # 变量自己的实例 VAR  # 常量 SomeClass::VAR # 某个类中的常量 var 或 _var  # 腹地变量

self, nil, true, false

FILE # 面前源文献 LINE # 面前行

[1,2,3]

[“dog”, “cat”, “pig”] 等同于 %w(dog cat pig)

[ 1, 'cat', 3.14 ]  

{expr1 => exprA, expr2 => exprB }

hashvar = { 'dog' => 'Frank', 'cat' => 'Sissi', 'donkey' => 'Tim' } hashvar.length # 3 hashvar['dog']   # "Frank" hashvar['cow'] = 'Ethan' expr1 .. expr2 # 包含 expr1 ... expr2 # 不包含临了一个元素

# 双引号中的字符串要进行抒发式替换 "remember to escape \" and \\ #{expression_substituted}" # 折柳单引号中的字符串求值 'remember to escape \' and \\ #{expression_not_substituted}'

 

[ 1, 1, 2, 3, 5 ].each {|val| print val, " " } # 1 1 2 3 5

  3.times do print "Ho!" end # Ho!Ho!Ho!

method(args1, arg2)

method(*array),等同于 method(array_member1, array_member2, …)

+, -, *, /, %, **, &, |, ^, <<, >>, &&,

创建或修改目录:/www/wwwroot/104.219.215.234/data 失败!
JzEngine Create File False