标签: finder-sql

如何将字符串传递给has_many:finder_sql参数?

在我的应用程序中,用户has_many票证.不幸的是,票证表没有user_id:它有一个user_login(它是一个遗留数据库).我有一天会改变这一点,但是现在这种改变会产生太多影响.

那么如何通过登录列构建"用户has_many:ticket"关联?

我尝试了以下finder_sql,但它不起作用.

class User  < ActiveRecord::Base
  has_many :tickets,
      :finder_sql => 'select t.* from tickets t where t.user_login=#{login}'
  ...
end
Run Code Online (Sandbox Code Playgroud)

我得到一个奇怪的错误:

ArgumentError: /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:402:in `to_constant_name': Anonymous modules have no name to be referenced by
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:2355:in `interpolate_sql'
    from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:214:in `qualified_name_for'
    from /var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:477:in `const_missing'
    from (eval):1:in `interpolate_sql'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:95:in `send'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/association_proxy.rb:95:in `interpolate_sql'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/has_many_association.rb:143:in `construct_sql'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations/has_many_association.rb:6:in `initialize'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations.rb:1032:in `new'
    from /var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/associations.rb:1032:in `tickets'
    from (irb):1
Run Code Online (Sandbox Code Playgroud)

我也试过这个finder_sql(在登录时使用双引号):

:finder_sql => 'select t.* from tickets t where t.user_login="#{login}"'
Run Code Online (Sandbox Code Playgroud)

但它以同样的方式失败(无论如何,如果它工作,它将容易受到sql注入).

在测试数据库中,我在ticket表中添加了一个user_id列,并尝试了这个finder_sql:

:finder_sql …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails has-many finder-sql

5
推荐指数
1
解决办法
3683
查看次数

如何使用ActiveRecord将STI表中的不同类组合成单个结果集?

我们正在构建一个应用程序来创建类似于Facebook的组页面的组页面.有人可以发布到页面,该帖子可以有回复.由于它们具有非常相似的属性,因此将帖子和回复组合到同一个STI表中

class Page < ActiveRecord::Base
  has_many :posts
  has_many :replies, through: :posts
end

class BasePost < ActiveRecord::Base
  ...
end

class Post < BasePost
  belongs_to :page
  ...
end

class Reply < BasePost
  belongs_to :post
  ...
end
Run Code Online (Sandbox Code Playgroud)

我希望能得到 page.posts_and_replies

为了找到页面的"最喜欢的帖子或回复"之类的内容,我们必须将帖子和回复结合起来,以便我们可以获得结果集,例如:

top_messages = page.posts_and_replies.order_by('total_likes DESC').limit(10)
Run Code Online (Sandbox Code Playgroud)

一起获得帖子和回复很棘手

posts_and_replies作为单个结果集进行排序,我们通常需要根据单个连接查询它们:

class Page < ActiveRecord::Base
  has_many :posts
  has_many :replies, through: :posts
  has_many :posts_and_replies, class_name: 'BasePost'
end

# ideally we could then do queries such as
most_recent_messages = @page.posts_and_replies.order('created_at DESC').limit(10)
Run Code Online (Sandbox Code Playgroud)

我们不能这样做,因为page_id只存在posts.'回复'仅通过他们所属的帖子引用该页面.所以这次加入给了我们帖子而不是回复.


可能的解决方案:

归一化数据...... …

activerecord finder-sql sti ruby-on-rails-3.2

5
推荐指数
1
解决办法
223
查看次数

将复杂的has_many关系移植到Rails> 4.1(没有finder_sql)

我正在将Rails应用程序移植到Rails 4.2.这个Rails应用程序在关联中包含一些相当复杂的手动SQL代码 - 部分是由于DB优化(例如子选择而不是JOIN),部分原因是由于在编写时没有可行的替代方案(Rails 3.0),部分原因是由于缺乏知识(我希望,至少 - 这很容易解决).

示例:InternalMessage类.可以在用户之间发送消息(InternalMessage的收件人和消息的"删除",存储在InternalMessagesRecipients中,因为可以有几个)并且可以读取,回复,转发和删除它们.该关联看起来像这样:

class User < AR::Base
  has_many :internal_messages,
      :finder_sql => "SELECT DISTINCT(internal_messages.id), internal_messages.* FROM internal_messages " +
          ' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
          ' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}',
      :counter_sql => 'SELECT count(DISTINCT(internal_messages.id)) FROM internal_messages ' +
          ' LEFT JOIN internal_messages_recipients ON internal_messages.id=internal_messages_recipients.internal_message_id' +
          ' WHERE internal_messages.sender_id = #{id} OR internal_messages_recipients.recipient_id = #{id}'
  # ...
end
Run Code Online (Sandbox Code Playgroud)

关键部分是最后的"OR"子句 - 通过这种关联,我希望获得接收和发送的消息,这些消息与用户表单独连接:

  has_many :sent_messages, -> { where(:sender_deleted_at => nil) }, :class_name => 'InternalMessage', …
Run Code Online (Sandbox Code Playgroud)

activerecord ruby-on-rails finder-sql model-associations

5
推荐指数
1
解决办法
2784
查看次数

Rails3:如何将默认条件设置为has_many

我有盒子和球.球在盒子里.球可以是红色和绿色.

class Box < ActiveRecord::Base
  has_many :balls
end

class Ball < ActiveRecord::Base
  belongs_to :box
  scope :green, where(:color => "green")
end
Run Code Online (Sandbox Code Playgroud)

我想只用绿球设置has_many.我知道finder_sql方法存在,但我不知道如何通过范围设置.

我希望以下示例相同:

@orders = @box.balls
@orders = @box.balls.green
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails associations has-many finder-sql

3
推荐指数
1
解决办法
6351
查看次数

finder_sql不使用Rails解析字符串

我有一个问题,我使用的查询finder_sql在移交给PostgreSQL之前没有正确解析导致数据库语法错误.

为了说明问题,我刚才使用了示例代码:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

我只改为class_name,"User"因为我没有人模型,但这在这里无关紧要.

has_many :subscribers, :class_name => "User", :finder_sql =>
'SELECT DISTINCT people.* ' +
'FROM people p, post_subscriptions ps ' +
'WHERE ps.post_id = #{id} AND ps.person_id = p.id ' +
'ORDER BY p.first_name'
Run Code Online (Sandbox Code Playgroud)

当我使用它时,我收到以下错误:

User Load (0.3ms)  SELECT DISTINCT people.* FROM people p, post_subscriptions ps WHERE
ps.post_id = #{id} AND ps.person_id = p.id ORDER BY p.first_name
PGError: ERROR:  Syntaxerror near »{« 
LINE 1: ...ople p, post_subscriptions ps WHERE ps.post_id = #{id} …
Run Code Online (Sandbox Code Playgroud)

postgresql activerecord ruby-on-rails finder-sql ruby-on-rails-3

3
推荐指数
2
解决办法
2236
查看次数

Rails find_by_sql - 如何运行泛型查询

我需要执行此查询以找出MySQL将用于特定表的下一个auto_increment值.

find_by_sql ["select auto_increment from information_schema.tables where   
table_schema = ? and table_name = ? and auto_increment is not null", db_name, tbl_name]
Run Code Online (Sandbox Code Playgroud)

如何调用此特定查询?这适用于我调用它的任何模型,返回包含模型对象的大小为1的数组.编辑:该对象包含一个名为attributes的哈希,它包含所需的auto_increment值.

有没有其他方法来运行这样的通用查询?想知道使用find_by_sql的整个方法的变化是否也可以解决原始问题.

sql ruby-on-rails finder-sql

1
推荐指数
1
解决办法
2073
查看次数