我有一个应用程序,其中有书籍中的引言,以及对引言的注释或想法。我想按照书的顺序、章节的顺序、页的顺序列出引文。
有没有办法将其移动到模型内的范围以保留 ActiveRelation?
喜欢
class Quote
scope :sorted, ->(order_of_books|book|) { where("reference_book = ?", book) }
end
我的控制器中有如下代码,它负责按图书顺序对报价进行排序。
# /app/controllers/quotes_controller.rb
def quotes
@quotes = Quotes.all
@sorted_quotes = []
order_of_books.each do |book|
@temp_array = []
if @quotes.any? { |quote| quote[:reference_book] == book}
@temp_array << @quotes.detect { |quote| quote[:reference_book] == book}
# @temp_array.sort_by! { |quote| quote.reference_paragraph, quote.reference_sentence }
@sorted_quotes << @temp_array
end
end
end
# /app/models/concerns/book_concern.rb
def order_of_books
[
"Book A",
"Book B",
"Book C",
]
end
这是数据库表供参考。
# db/schema.rb
create_table "quotes", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "text", null: false
t.string "reference_book", null: false
t.integer "reference_chapter", null: false
t.integer "reference_paragraph", null: false
t.integer "reference_sentence", null: false
t.string "image"
t.text "notes"
end
错误
现在的问题是,我正在尝试对引号进行排序,当我尝试调用类似
quote.image
的内容时,我的所有其他代码都被破坏了,并且收到此错误:
undefined method `image' for [#<Quote id: 4, created_at: "2023-11-21 15:19:....
旁注
控制器中我尝试
sort_by!
段落和句子的行不起作用,所以我只是将其注释掉。现在这对我来说并不那么重要。
`
我找到了一个解决方法。它确实not回答了我创建
scope
的最初问题,但它确实解决了我的代码不适用于像quote.image
这样的实例的问题
解决方案
在我的控制器中,当我编码时:
@temp_array << @quotes.detect { |quote| quote[:reference_book] == book}
@sorted_quotes << @temp_array
它将 ActiveRelation 放入数组元素中,然后将其保存到
@temp_array
;这是因为 detect
将所有实例从与搜索项匹配的一个数组中拉出。因此,我只需要通过迭代 @temp_array
并将每个元素添加到 @sorted_quotes
来撤消此操作,而不是添加整个元素。
这是我的更改(还更改了一些变量,使其不是“全局”的,因为在这种情况下不需要这样做。
def quotes
quotes = Quote.all
@sorted_quotes = []
order_of_books.each do |book|
temp_array = []
if quotes.any? { |quote| quote[:reference_book] == book}
temp_array << quotes.detect { |quote| quote[:reference_book] == book}
temp_array.each do |q|
@sorted_quotes << q
end
end
end
end
这解决了问题。我可以保留这个问题,因为这个解决方案在技术上并没有回答关于制定范围来做同样的事情的最初问题。