Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions app/lib/discord/events/puzzle_answer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,29 @@
return
end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this as it was repetitive.

server = Server.find_or_initialize_by(server_id: event.server.id)

# Create the answer record
answer = Answer.create!(
answer = Answer.create(
puzzle_id: puzzle.id,
user_id: user.id,
server_id: server.id,
choice: answer, # 'ruby' or 'rails'
is_correct: puzzle.answer.to_s == answer # Correct answer check
)

# Respond to the user with the result
event.respond(
content: nil,
embeds: [ answer_embed(answer, puzzle) ],
ephemeral: true # Only the user sees this message
)
if answer
# Respond to the user with the result
event.respond(
content: nil,
embeds: [ answer_embed(answer, puzzle) ],
ephemeral: true # Only the user sees this message
)
else
Copy link
Member Author

@FionaDL FionaDL Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking further into this it seems as though answer should always be nil if the validation fails or the db index unique fails, so the if/else should work here.

# If the user has already answered, prevent them from changing their answer
event.respond(
content: "You have already answered this puzzle. You cannot change your answer.",
ephemeral: true # Only the user sees this message
)
return

Check failure on line 64 in app/lib/discord/events/puzzle_answer.rb

View workflow job for this annotation

GitHub Actions / lint

Style/RedundantReturn: Redundant `return` detected.
end
end

private
Expand Down
2 changes: 2 additions & 0 deletions app/models/answer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Answer < ApplicationRecord
belongs_to :puzzle
belongs_to :user

validates :puzzle_id, uniqueness: { scope: [ :user_id, :server_id ] }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an extra layer of validation

end
1 change: 1 addition & 0 deletions app/models/server.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class Server < ApplicationRecord
has_and_belongs_to_many :users, join_table: "users_servers"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure how this was working before

has_one :channel
end
4 changes: 2 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class User < ApplicationRecord
has_and_belongs_to_many :servers
has_many :servers
has_and_belongs_to_many :servers, join_table: "users_servers"
has_many :answers
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove repetitive servers, I think this must have been a mistake and was supposed to be answers.


enum :role, admin: 0, member: 1
end
5 changes: 5 additions & 0 deletions db/migrate/20250917170711_add_unique_index_to_answers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddUniqueIndexToAnswers < ActiveRecord::Migration[8.0]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add migration with db uniqueness for each answer

def change
add_index :answers, [ :puzzle_id, :user_id, :server_id ], unique: true, name: 'index_answers_on_puzzle_user_server'
end
end
4 changes: 2 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 60 additions & 23 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@

# db/seeds.rb

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While testing this in the rails console I was having several issues so I updated the seed file to more closely resemble the relationships.

# Create Puzzle records
Puzzle.create!([
{ question: "Ruby or Rails provided this method? Array.new(5) { |i| i * 2 }", answer: :ruby, explanation: "`Array.new` is a core Ruby method that creates a new array with a specified size and optional block for initialization. This is part of Ruby’s core library." },
{ question: "Ruby or Rails provided this method? File.open('log.txt', 'w') { |file| file.write('Hello, World!') }", answer: :ruby, explanation: "`File.open` is a core Ruby method for opening files. It’s part of Ruby's standard library for file handling, not part of Rails." },
{ question: "Ruby or Rails provided this method? render json: @user", answer: :rails, explanation: "`render json:` is a Rails method used to render a JSON response from a controller action." },
{ question: "Ruby or Rails provided this method? link_to 'Home', root_path", answer: :rails, explanation: "`link_to` is a Rails helper method that generates HTML links. `root_path` is a Rails path helper." },
{ question: "Ruby or Rails provided this method? params[:id]", answer: :rails, explanation: "`params[:id]` is used in Rails to fetch query parameters or URL parameters in controller actions." }
])
# ====== Create Puzzle records ======
puzzles = [
{
question: "Ruby or Rails provided this method? Array.new(5) { |i| i * 2 }",
answer: :ruby,
explanation: "`Array.new` is a core Ruby method that creates a new array with a specified size and optional block for initialization. This is part of Ruby’s core library."
},
{
question: "Ruby or Rails provided this method? File.open('log.txt', 'w') { |file| file.write('Hello, World!') }",
answer: :ruby,
explanation: "`File.open` is a core Ruby method for opening files. It’s part of Ruby's standard library for file handling, not part of Rails."
},
{
question: "Ruby or Rails provided this method? render json: @user",
answer: :rails,
explanation: "`render json:` is a Rails method used to render a JSON response from a controller action."
},
{
question: "Ruby or Rails provided this method? link_to 'Home', root_path",
answer: :rails,
explanation: "`link_to` is a Rails helper method that generates HTML links. `root_path` is a Rails path helper."
},
{
question: "Ruby or Rails provided this method? params[:id]",
answer: :rails,
explanation: "`params[:id]` is used in Rails to fetch query parameters or URL parameters in controller actions."
}
]

puzzles.each do |p|
Puzzle.find_or_create_by!(question: p[:question]) do |puzzle|
puzzle.answer = p[:answer]
puzzle.explanation = p[:explanation]
end
end

# Create a server
Server.create!(server_id: 1179555097060061245, name: "OmbuTest")
# ====== Create the Server ======
server = Server.find_or_create_by!(server_id: 1179555097060061245) do |s|
s.name = "OmbuTest"
end

# Seed data for 10 users with answers
# ====== Create Users and associate with Server ======
users = [
{ user_id: 101, username: "user1", role: "member" },
{ user_id: 102, username: "user2", role: "member" },
Expand All @@ -28,16 +56,25 @@
]

users.each do |user_data|
user = User.create(user_id: user_data[:user_id], username: user_data[:username], role: user_data[:role])

# Randomly assign scores to answers (you can adjust as needed)
3.times do
Answer.create!(
user_id: user.id,
puzzle_id: Puzzle.all.sample.id,
server_id: Server.first.id,
choice: [ "ruby", "rails" ].sample,
is_correct: [ true, false ].sample
)
user = User.find_or_create_by!(user_id: user_data[:user_id]) do |u|
u.username = user_data[:username]
u.role = user_data[:role]
end

# Associate user with the server if not already linked
user.servers << server unless user.servers.include?(server)

# Seed random answers for this user if they have none
if user.answers.where(server_id: server.id).empty?
3.times do
Answer.create!(
user_id: user.id,
puzzle_id: Puzzle.all.sample.id,
server_id: server.id,
choice: ["ruby", "rails"].sample,

Check failure on line 74 in db/seeds.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.

Check failure on line 74 in db/seeds.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.
is_correct: [true, false].sample

Check failure on line 75 in db/seeds.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.

Check failure on line 75 in db/seeds.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/SpaceInsideArrayLiteralBrackets: Use space inside array brackets.
)
end
end
end

Check failure on line 80 in db/seeds.rb

View workflow job for this annotation

GitHub Actions / lint

Layout/TrailingEmptyLines: 1 trailing blank lines detected.
Loading