我找不到如何使用rom-sql提取别名列的方法。
赋予用户和化身的关系(用户具有多个化身)。
# works
users.join(:avatars).select { |r| r.avatars[:id] }.pluck(:id)
# does not work
users.join(:avatars).select { |r| r.avatars[:id].as(:avatar_id) }.pluck(:avatar_id)
# NoMethodError: undefined method `[]' for nil:NilClass
# from /usr/local/bundle/gems/rom-core-4.2.1/lib/rom/schema.rb:195:in `[]'
# more examples
users.join(:avatars).select{|r| r.avatars[:id].as('avatar_id')}
#=> #<Persistence::Relations::Users name=ROM::Relation::Name(users) dataset=#<Sequel::Postgres::Dataset: "SELECT \"avatars\".\"id\" AS \"avatar_id\" FROM \"users\" INNER JOIN \"avatars\" ON (\"users\".\"id\" = \"avatars\".\"user_id\") ORDER BY \"users\".\"id\"">>
users.join(:avatars).select{|r| r.avatars[:id].as('avatar_id')}.to_a
#> Dry::Struct::Error: [Entities::User.new] :avatar_id is missing in Hash input
users.join(:avatars).select{|r| r.avatars[:id].as('avatar_id')}.with(auto_struct: false).to_a
#=> [{:avatar_id=>88}, {:avatar_id=>89}]
答案 0 :(得分:0)
如果未指定所用库的版本,则不可能提出任何解决方案。对于rom-sql 2.4.0
,它就可以使用:
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'bundler/inline'
gemfile(false) do
source 'https://rubygems.org'
gem 'sqlite3'
gem 'rom-sql', '2.4.0'
gem 'rspec'
end
require 'rspec'
require 'rspec/autorun'
require 'dry-types'
require 'rom-sql'
require 'sqlite3'
RSpec.describe do
let(:uri) { 'sqlite::memory' }
let(:conn) { Sequel.connect(uri) }
let(:conf) { ROM::Configuration.new(:sql, conn) }
let(:container) { ROM.container(conf) }
let(:avatars) { container.relations[:avatars] }
let(:users) { container.relations[:users] }
before do
conn.create_table(:avatars) do
primary_key :id
Integer :user_id
String :url
end
conn.create_table(:users) { primary_key :id }
conf.relation(:avatars) do
schema(infer: true) do
associations do
belongs_to :user
end
end
end
conf.relation(:users) do
schema(infer: true) do
associations do
has_many :avatars
end
end
end
end
subject(:relation) do
users.join(:avatars).select { relations[:avatars][:url].as(:avatar_url) }
end
it do
users.insert
avatars.insert(user_id: 1, url: 'avatars/1')
avatars.insert(user_id: 1, url: 'avatars/2')
expect { relation.pluck(:avatar_url) }.not_to raise_error
expect(relation.pluck(:avatar_url)).to eq ['avatars/1', 'avatars/2']
end
end