标签: rails-activerecord

Ruby on Rails ::包含与子模型的多态关联

使用多态关联时,是否可以在仅存在于某些类型中的子模型上运行包含?

例:

class Container
  belongs_to :contents, :polymorphic => true
end
class Food
  has_one :container
  belongs_to :expiration
end
class Things
  has_one :container
end
Run Code Online (Sandbox Code Playgroud)

在视图中我想要做的事情如下:

<% c = Containers.all %>
<% if c.class == Food %>
  <%= food.expiration %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

因此,当我加载c时,我想急切加载到期,因为我知道我将需要最后一个.有没有办法这样做?只定义一个常规:include得到我的错误,因为并非所有封闭类型都有子模型到期.

ruby-on-rails include polymorphic-associations eager-loading rails-activerecord

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

Rails 3 - 渴望加载条件

好的,我对这一点感到非常难过.我正在尝试构建按类别组织的已发布网页的菜单.

Category.rb:

belongs_to :parent, :class_name => "Category", :foreign_key => "parent_id"
has_many   :children, :class_name => "Category", :foreign_key => "parent_id"
has_many :pages, :documents, :galleries
Run Code Online (Sandbox Code Playgroud)

Page.rb

belongs_to :category
Run Code Online (Sandbox Code Playgroud)

Page模型也有:is_published,所以我也试图对它进行过滤.我不愿意发布我的微弱查询尝试,但除了乞求更聪明的人之外,没有其他解决方案:

(自我是@current_website)

self.categories.includes(:children, :pages).where('pages.is_published = 1')
Run Code Online (Sandbox Code Playgroud)

这主要返回我需要的内容,但不返回没有发布页面的父类别.例如,如果我有:

Parent Category
- Published Page
- Child Category
-- Published Page
Run Code Online (Sandbox Code Playgroud)

失败的地方是我父母没有发布的页面,如下所示:

Parent Category
- Child Category
-- Published Page
- Child Category
-- Published Page
Run Code Online (Sandbox Code Playgroud)

在此先感谢任何帮助.我正在尽可能多地学习有关查询的内容,但我在这方面已经反对了.

更新:实现KandadaBoggu的建议已经产生了更好的结果,这被添加到Category.rb

  has_many :published_pages, :class_name => "Page",
                             :conditions => {:is_published => true}
Run Code Online (Sandbox Code Playgroud)

但是,使用以下内容时:

self.categories.where(:parent_id => nil).includes({:children => :published_pages},
                                                   :published_pages)
Run Code Online (Sandbox Code Playgroud)

我得到了我需要的结果,但我也得到了空的父类别(没有published_pa​​ges,没有已发布页面的子类别.例如:

- Parent …
Run Code Online (Sandbox Code Playgroud)

mysql ruby-on-rails rails-activerecord

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

在阵列上运行destroy_all?

我怎样才能destroy_all在阵列上运行?

我有以下查询:

spam_users = User.find_by_sql("SELECT * FROM users WHERE email ~* '21cn.com'")
Run Code Online (Sandbox Code Playgroud)

我试过跑spam_users.destroy_all但是得到了undefined method 'destroy_all' for #<Array:0x10b09ce30>.

我在这个特定的应用程序中运行Rails 2.3.8以及PostgreSQL.

postgresql activerecord ruby-on-rails rails-activerecord

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

是否可以使用活动记录为表定义复合主键?

我在没有rails的ruby项目中使用ActiveRecord.我需要为表定义复合主键.通常,迁移会自动创建主键.是否可以使用活动记录为表定义自己的复合主键?

ruby rubygems rails-activerecord

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

在Rails中使用Postgres UUID时,请避免PG :: InvalidTextRepresentation错误

我开始使用Postgres UUID类型用于我所有模型的id字段.非常好用,并且在Rails 4中支持(大部分):

create_table :users, id: :uuid do |t|
  # ...
end
Run Code Online (Sandbox Code Playgroud)

问题是,如果您尝试查找id为X的行,但Postgres将引发错误,但X不是格式正确的UUID字符串.

> User.find "3ac093e2-3a5e-4744-b49f-117b032adc6c"
ActiveRecord::RecordNotFound # good, will cause a 404
> User.find "foobar"
PG::InvalidTextRepresentation: ERROR # bad, will cause a 500
Run Code Online (Sandbox Code Playgroud)

因此,如果我的用户位于URL中UUID所在的页面上,然后他们尝试更改UUID,则会得到500错误而不是404.或者他们可能会获得一个不再存在的对象的链接.

我怎样才能以干燥的方式避免这种情况?我不能只是拯救PG::InvalidTextRepresentation和渲染404,因为其他东西也可能导致这个错误.

UPDATE

我认为ID参数格式的正则表达式是干净的,如果它不匹配则会引发404:

resources :users, id: /uuid-regex-here/
Run Code Online (Sandbox Code Playgroud)

但我仍然有待保持干燥的问题; 我不想把它放在我的路线中的每一个资源上.我可以在一个语句中声明多个资源,但前提是不要像成员操作那样使用其他选项.所以也许更好的问题是:有没有办法为所有路由设置id正则表达式?

postgresql ruby-on-rails rails-postgresql ruby-on-rails-4 rails-activerecord

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

ActiveRecord渴望加载多个belongs_to关联

问题

我有以下ActiveRecord模型:

class Person
  belongs_to :favourite_car, class_name: 'Car'
  belongs_to :business_car, class_name: 'Car'
  belongs_to :home_car, class_name: 'Car'
end
Run Code Online (Sandbox Code Playgroud)

当我想访问所有这三个关联时,它会生成三个选择查询:

SELECT * FROM cars WHERE cars.id = ?
Run Code Online (Sandbox Code Playgroud)

这基本上是N + 1问题.

理想情况下,我希望它只生成一个表单查询

SELECT * FROM cars WHERE cars.id IN (?, ?, ?)
Run Code Online (Sandbox Code Playgroud)

可能解决方案

我可以将它移动到has_many :through => :join_table与连接表中的列的关联,以指示关联类型是什么,然后用于includes([:join_table, :cars])急切加载关联.但是,在这种情况下,它只将3个查询减少到2,并引入了一个额外的表.

另一种可能的解决

另一种可能的解决方案是手动加载关联,如下所示:

module EagerLoader
  def eager_load(*associations)
    reflections = associations.map { |association| self.class.reflections[association.to_sym] }
    raise 'Not all are valid associations' if reflections.any?(&:nil?)

    reflections.group_by { |association| association.klass }.each do |klass, …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails eager-loading rails-activerecord

10
推荐指数
2
解决办法
7906
查看次数

如何通过'rails g migration'命令向要添加的列添加默认值

我知道如何在已创建的迁移文件中添加默认值.即

`rails generate migration AddTestColumnToTesttable test_status:boolean` to create it.
Run Code Online (Sandbox Code Playgroud)

它将生成此迁移:

class AddTestColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :test_status, :boolean, :default => true
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,我们可以通过rails g migration命令本身添加默认值吗?

ruby-on-rails database-migration rails-activerecord

10
推荐指数
2
解决办法
2万
查看次数

基于枚举值的自定义顺序

我为角色定义了Enum:

enum role: {ordinary: 0, manager: 1, admin: 2}
Run Code Online (Sandbox Code Playgroud)

我想按以下顺序订购一组对象:

admin (first all admins)
ordinary (then all ordinaries)
manager (and lastly all managers)
Run Code Online (Sandbox Code Playgroud)

这有可能吗?

enums activerecord ruby-on-rails rails-activerecord ruby-on-rails-5

10
推荐指数
3
解决办法
2840
查看次数

委托has_many关联方法忽略预加载

是否可以将一个方法委托给has_manyrails中的关联,并且仍然按照demeter定律保存该关联上的预加载数据?目前在我看来,你被迫选择其中一个.即:通过NOT委托保留预加载的数据,或丢失预加载的数据和委托.

示例:我有以下两个模型:

class User < ApplicationRecord
  has_many :blogs

  delegate :all_have_title?, to: :blogs, prefix: false, allow_nil: false

  def all_blogs_have_title?
    blogs.all? {|blog| blog.title.present?}
  end
end


class Blog < ApplicationRecord
  belongs_to :user

  def self.all_have_title?
    all.all? {|blog| blog.title.present?}
  end
end
Run Code Online (Sandbox Code Playgroud)

注意:这User#all_blogs_have_title?与委托方法完全相同all_have_title?.

根据我的理解,以下内容违反了德米特定律.但是:它维护您的预加载数据:

user = User.includes(:blogs).first
  User Load (0.1ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  Blog Load (0.1ms)  SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" = 1
  => #<User id: 1, name: "all yes", …
Run Code Online (Sandbox Code Playgroud)

ruby activerecord ruby-on-rails associations rails-activerecord

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

使用 ActiveRecord 在 PostgreSQL 中创建包含索引列和“INCLUDE”列的索引

我想要创建的是索引之一,其中一些列被索引,另一些列被包含。PostgreSQL 在其文档中描述了这种索引

创建索引的 SQL 查询看起来像CREATE INDEX tab_x_y ON tab(x) INCLUDE (y);

在此处查看 ActiveRecord PostgreSQL 适配器文档

我没有看到任何使用此INCLUDE列功能的选项。

我必须将其作为原始 SQL 查询运行吗?还有别的办法吗?

笔记

  1. 我不是问如何运行查询或查询将使用哪个索引。
  2. 我不是问如何使用 ActiveRecord 创建常规索引。
  3. 我不是问如何使用 ActiveRecord 创建迁移。
  4. 我特别想要有关如何使用特定选项创建特定类型索引的信息。

postgresql ruby-on-rails rails-activerecord

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