我正在尝试将模型中的原始SQL查询转换为使用ActiveRecord查询接口。我认为我正确地翻译了这个查询,但是我不能将它转换成一个数组来呈现它。
这是我的模型:
class Pgdb < ActiveRecord::Base
self.abstract_class = true
self.table_name = 'test'
if Rails.env.development?
establish_connection :pg_development
end
def self.getInfo(name)
get = Pgdb.where(city: "New York")
get_a = get.to_a
get_a
end
end
我能够呈现的原始SQL查询是:
get = connection.query("SELECT * FROM test WHERE city = "New York")
正如上面的代码所示,我正在访问一个外部PostgreSQL数据库,并尝试使用#to_a
将ActiveRecord对象转换为数组,但这是行不通的。在我看来,当我试图渲染它时:
<% @info.each do |row| %>
<tr>
<% row.each do |element| %>
<td><%= element %></td>
<% end %>
</tr>
<% end %>
我得到了一个错误:undefined method 'each' for #<Pgdb:0x007fd37af79040>
。我尝试过在代码中的不同位置对对象使用to_a
,但是没有什么效果。
控制器
def index
end
def new
@thing = Thing.new
end
def create
@info = Pgdb.getInfo(@thing.something)
render :index
end
发布于 2015-08-02 17:06:24
您正在接收Pgdb
实例的错误Pgdb
,因为您的代码试图迭代此行中实例的数据属性:
<% row.each do |element| %>
ActiveRecord实例不是可以迭代的属性集合。相反,它们是响应以其属性命名的消息的对象。换句话说,你可以这样做:
p = Pgdb.first
p.city # because the underlying table has a `city` attribute
但你不能这么做
p.each { |attribute| puts attribute }
但是,ActiveRecord为这件事提供了attributes
访问器。attributes
方法返回可以使用each
方法迭代的散列。因此,您可以这样做:
p.attributes.each { |key, value| puts "#{key}: #{value}" }
在您的视图中,您可以用以下内容替换内部循环:
<% row.attributes.each do |key, value| %>
<td><%= "#{key}: #{value}" %></td>
<% end %>
这将呈现Pgdb
实例的属性。
顺便说一句,没有必要将where
的结果转换为Pgdb::getInfo
中的一个Array
。where
查询返回响应each
的ActiveRecord::Relation
对象,以及类似于数组的map
和select
等其他Enumerable
消息。在您的代码中,您将成功地在
<% @info.each do |row| %>
无论您是否在to_a
中使用getInfo
,这都是可行的。有很好的理由不将结果集转换为数组。首先,ActiveRecord::Relation
对象具有其他功能,比如作用域,您可能经常需要使用这些功能。
希望这能有所帮助。编码愉快!
发布于 2015-08-02 16:52:44
将rails连接到外部数据库的正确方法是使用config/database.yml
文件:
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
#
defaults: &defaults
adapter: postgresql
encoding: utf8
template: template0
# used for test & development
local:
host: localhost
username: j_random_user # change this!
password: p4ssword # change this!
development:
<<: *defaults
<<: *local
database: my_app_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *defaults
<<: *local
database: my_app_test
production:
<<: *defaults
host: "my_app_something.rds.amazonaws.com" # change this!
username: my_amazon_db_user # change this!
password: my_amazon_user # change this!
reconnect: true
port: 3306
您可能希望使用本地postgres数据库进行开发,并将生产数据库镜像为pgbackup。
但是,您的主要问题是,在创建rails应用程序时,您所做的一切都是错误的。这看起来像一个PHP示例,在这个例子中,某个无知的灵魂正在第1000次重新创建数据库管理器。
下面是Rails MVC和ActiveRecord速成课程:
模型反映了您域中的对象。假设我们有宠物商店的应用程序。
当然,我们需要宠物模型:
$ rails g model Pet name:string
$ rake db:migrate
这将在数据库中创建一个pets
表和一个Pet
类。注意,表名是复数的,模型名是单数的。
# app/models/pet.rb
class Pet < ActiveRecord::Base
end
然后,我们可以通过以下方式访问宠物:
Pet.all
Pet.find(1) # find pet where id is 1
# ... etc
我们可以通过以下方式创造宠物:
pet = Pet.create(name: "Spot")
所有这些都包含在大多数基本rails教程中。
没有模型的连接。
ActiveRecord::Base.establish_connection
con = ActiveRecord::Base.connection
res = con.execute('SELECT * FROM foo')
尽管如果您不实际使用每个表的模型并在某种程度上遵循MVC约定,那么使用ActiveRecord实际上就没有意义。这是可能的,但它并没有给你真正的好处。
同样,没有MVC的Rails也是可行的,但有什么意义呢?
使用遗留数据库
假设您有一个遗留数据库,它是由一些人编写的,尽管他们使用Apps匈牙利语作为数据库列(耸耸肩)是很酷的:
persons:
intPersonID: Integer, Autoincrement, Primary Key
你想把它映射到一个Rails模型
class User < ActiveRecord::Base
self.table_name 'persons'
self.primary_key 'intPersonID'
end
或者在你的情况下:
class Test < ActiveRecord::Base
self.table_name 'test' # since it's not "tests"
end
Test.where(city: "New York")
https://stackoverflow.com/questions/31777824
复制