gpt4 book ai didi

ruby-on-rails - 如何在没有支持表的情况下在 Rails 中创建只读模型

转载 作者:行者123 更新时间:2023-12-02 04:27:40 29 4
gpt4 key购买 nike

我想创建只读模型,该模型可能是某些复杂的结果与任何直接表模型类关系不大的联接或聚合查询我已经定义了。

例如想象中的 ActiveRecord::View 类

class B < ActiveRecord::View
default_scope do
find_by_sql <<-EOF
select x.alpha alpha, y.a_id a_id from
x.join y on x.id = y.id
EOF
end

belongs_to :a
end

class A < ActiveRecord::Base
has_many :b
end

>> a = A.first
>> puts a.id

10

>> puts a.bs.to_sql

select x.alpha alpha, y.a_id a_id from
x.join y on x.id = y.id
where a_id = 10

我确信上述内容或类似内容可用,但我就是找不到。

最佳答案

我发布了一个 Ruby GEM 来解决这个问题

https://github.com/bradphelan/Active-Illusion

验证行为的规范文件是

require 'rubygems'
require 'active_illusion'
require 'squeel'

TIMES = (ENV['N'] || 10000).to_i

require 'rubygems'
require "active_record"

conn = { :adapter => 'sqlite3', :database => ':memory:' }
ActiveRecord::Base.establish_connection(conn)

class User < ActiveRecord::Base
connection.create_table :users, :force => true do |t|
t.string :name, :email
t.timestamps
end

has_many :exhibits
end

class Exhibit < ActiveRecord::Base
connection.create_table :exhibits, :force => true do |t|
t.belongs_to :user
t.string :name
t.text :notes
t.integer :ssn
t.timestamps
end

belongs_to :user

def look; attributes end
def feel; look; user.name end

def self.look(exhibits) exhibits.each { |e| e.look } end
def self.feel(exhibits) exhibits.each { |e| e.feel } end
end

module ActiveRecord
class Faker
LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non aliquet diam. Curabitur vel urna metus, quis malesuada elit. Integer consequat tincidunt felis. Etiam non erat dolor. Vivamus imperdiet nibh sit amet diam eleifend id posuere diam malesuada. Mauris at accumsan sem. Donec id lorem neque. Fusce erat lorem, ornare eu congue vitae, malesuada quis neque. Maecenas vel urna a velit pretium fermentum. Donec tortor enim, tempor venenatis egestas a, tempor sed ipsum. Ut arcu justo, faucibus non imperdiet ac, interdum at diam. Pellentesque ipsum enim, venenatis ut iaculis vitae, varius vitae sem. Sed rutrum quam ac elit euismod bibendum. Donec ultricies ultricies magna, at lacinia libero mollis aliquam. Sed ac arcu in tortor elementum tincidunt vel interdum sem. Curabitur eget erat arcu. Praesent eget eros leo. Nam magna enim, sollicitudin vehicula scelerisque in, vulputate ut libero. Praesent varius tincidunt commodo".split
def self.name
LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join ' '
end

def self.email
LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join('@') + ".com"
end
end
end

class Test0 < ActiveRecord::Illusion
column :name
column :exhibition
column :number
#belongs_to :user, :foreign_key => :name

view do
User.joins{exhibits}.select{
[users.name.as(name), exhibits.name.as(xname), exhibits.ssn.as(number) ]
}
end
end

# pre-compute the insert statements and fake data compilation,
# so the benchmarks below show the actual runtime for the execute
# method, minus the setup steps

# Using the same paragraph for all exhibits because it is very slow
# to generate unique paragraphs for all exhibits.
notes = ActiveRecord::Faker::LOREM.join ' '
today = Date.today


describe ActiveRecord::Illusion do
before :each do

User.destroy_all

Exhibit.destroy_all

puts 'Inserting 100 users and exhibits...'
100.times do |i|
user = User.create(
:created_at => today,
:name => ActiveRecord::Faker.name,
:email => ActiveRecord::Faker.email
)

Exhibit.create(
:created_at => today,
:name => ActiveRecord::Faker.name,
:user => user,
:notes => notes,
:ssn => i
)
end

end

it "should have 100 users" do
User.count.should == 100
end

it "should have 100 exhibits" do
Exhibit.count.should == 100
end

describe Test0 do
it "should retrieve 100 rows" do
Test0.where{}.to_sql.should ==
%Q[SELECT \"test0s\".* FROM (SELECT \"users\".\"name\" AS name, \"exhibits\".\"name\" AS xname, \"exhibits\".\"ssn\" AS number FROM \"users\" INNER JOIN \"exhibits\" ON \"exhibits\".\"user_id\" = \"users\".\"id\") test0s ]
Test0.count.should == 100


Test0.where{number < 20}.to_sql.should ==
%Q[SELECT "test0s".* FROM (SELECT "users"."name" AS name, "exhibits"."name" AS xname, "exhibits"."ssn" AS number FROM "users" INNER JOIN "exhibits" ON "exhibits"."user_id" = "users"."id") test0s WHERE "test0s"."number" < 20]
Test0.where{number < 20}.count.should == 20
end
end
end

关于ruby-on-rails - 如何在没有支持表的情况下在 Rails 中创建只读模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6900508/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com