I have an app where there are quotes from books with notes or thoughts on the quotes. I want to list out the quotes in order of the book order, chapter order and then page order.
Is there a way to move this to a scope within the model in order to keep the ActiveRelation?
like
class Quote
scope :sorted, ->(order_of_books|book|) { where("reference_book = ?", book) }
end
I have code like the following in my Controller that does the job of ordering the quotes by book order.
# /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
This is the database table for reference.
# 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
Errors
The issue is now that I am trying to sort the quotes, all my other code is breaking when in my views when I try to call something like quote.image and I get this error:
undefined method `image' for [#<Quote id: 4, created_at: "2023-11-21 15:19:....
Side Note
The line in my controller where I try to sort_by! the paragraph and sentence isn't working so I just commented it out. Right now that isn't as important for me.
`
I found a workaround. It does not answer my initial question of creating a
scope, but it does solve the issue of my code not working for instances likequote.imageSolution
In my controller when I coded this:
it would put the ActiveRelation inside an array element and then save it to the
@temp_array; this is becauseselectpulls all of the instances out of one array that matches the search terms. So, I just needed to undo this by iterating through the@temp_arrayand adding each element to the@sorted_quotesinstead of adding the entire thing.Here are my changes (also changing some variables to not be 'global' as that's just not needed in this situation.
This fixed the issue. I can leave the question open as this solution does not technically answer the initial question about making a scope to do this same thing.