假设我有一个这样的简单模型,名为“name”的字段和名为“aliased_name”的属性:
class User < ActiveRecord::Base
attr_accessor :aliased_name
end
User.create(name: "Faye Kname")
我能做到:
user=User.select(:id, :name)
user.name # Faye Kname
但是如何使用select
填充aliased_name
属性。
user=User.select(:id, "name AS aliased_name")
user.aliased_name # nil
user[:aliased_name] # Faye Kname
我可以访问:aliased_name
符号,但未分配该属性。我不想做
user.aliased_name = user[:aliased_name]
我实际上正在另一个表上进行更复杂的连接,我正在尝试从连接表中选择一个字段到别名中,但我认为这是一个更简单的例子。
答案 0 :(得分:3)
通常,我使用方法而不是attr_accessors来执行这些别名。像
这样的东西def aliased_name
has_attribute?(:aliased_name) ? read_attribute(:aliased_name) : self.name
end
如果您没有在查询中加载属性,has_attribute?
就会存在,因此您可以使用默认值。
答案 1 :(得分:1)
所以attr_accessor正在寻找我认为你的代码中没有设置的实例变量@aliased_name
。您可以使用@aliased_name = "some value"
或使用attr_accessor aliased_name = "some value"
进行设置,但不会使用返回对象的初始查询进行设置,也不会在第二个SELECT查询中进行设置,至少在现在编写它时。
可能有意义的一条路线是使用单独的方法和attr_writer。像这样的东西
attr_writer :aliased_name
def aliased_name
@aliased_name ||= self.name
end
这会在第一次调用时设置实例变量,并让您可以使用attr_writer自由更改它。我不确定这是如何适应更复杂的连接,但这是解决您最初描述的问题的一种相当简单的方法。
答案 2 :(得分:1)
您最好使用alias_attribute
:
#app/models/user.rb
class User < ActiveRecord::Base
alias_attribute :aliased_name, :name
end
虽然只需要user.name
数据&amp;把它放进user.alias_attribute
我试图从连接表中选择一个字段到别名
之前完成此事:
您有两种选择。使用SQL ALIAS
列,或访问模型中的proxy_association
方法。我与两者都进行了广泛的合作:
-
SQL别名
#app/models/parent.rb
class Parent < ActiveRecord::Base
has_many :joins
has_many :children, -> { select("#{Parent.table_name}.*, #{Join.table_name}.attr AS alias_name") }, through: :joins, dependent: :destroy
end
这会给你......
@parent.children.each do |child|
child.alias_name
end
-
下一个方法要复杂得多;效率更高:
#app/models/parent.rb
class Parent < ActiveRecord::Base
has_many :joins
has_many :children, through: :joins, -> { extending AliasAttribute }
end
#app/models/concerns/alias_attribute.rb
module PlayerPermission
#Load
def load
alias_names.each do |permission|
proxy_association.target << permission
end
end
#Private
private
#Names
def names
return_array = []
through_collection.each_with_index do |through,i|
associate = through.send(reflection_name)
associate.assign_attributes({name: items[i]})
return_array.concat Array.new(1).fill( associate )
end
return_array
end
#######################
# Variables #
#######################
#Association
def reflection_name
proxy_association.source_reflection.name
end
#Foreign Key
def through_source_key
proxy_association.reflection.source_reflection.foreign_key
end
#Primary Key
def through_primary_key
proxy_association.reflection.through_reflection.active_record_primary_key
end
#Through Name
def through_name
proxy_association.reflection.through_reflection.name
end
#Through
def through_collection
proxy_association.owner.send through_name
end
#Captions
def items
through_collection.map(&:name)
end
#Target
def target_collection
#load_target
proxy_association.target
end
end
每次调用关联时,您都可以访问.association
对象。在关联本身内,您可以访问proxy_association
个对象;所有这些操作都可以将别名数据插入到父数据中。
以上将允许您使用:
@parent = Parent.find x
@parent.children.each do |child|
child.alias_name
end
如果需要,我可以提供支持。