Skip to content

Commit 72ce4c5

Browse files
authored
Merge pull request #23 from fastruby/IIRR-29
IIIRR-29 Update for issue in tables and prevent answer duplication
2 parents cf6ad3d + 3815353 commit 72ce4c5

File tree

7 files changed

+86
-36
lines changed

7 files changed

+86
-36
lines changed

app/lib/discord/events/puzzle_answer.rb

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,29 @@ def handle(event)
4040
return
4141
end
4242

43-
server = Server.find_or_initialize_by(server_id: event.server.id)
44-
4543
# Create the answer record
46-
answer = Answer.create!(
44+
answer = Answer.create(
4745
puzzle_id: puzzle.id,
4846
user_id: user.id,
4947
server_id: server.id,
5048
choice: answer, # 'ruby' or 'rails'
5149
is_correct: puzzle.answer.to_s == answer # Correct answer check
5250
)
53-
54-
# Respond to the user with the result
55-
event.respond(
56-
content: nil,
57-
embeds: [ answer_embed(answer, puzzle) ],
58-
ephemeral: true # Only the user sees this message
59-
)
51+
if answer
52+
# Respond to the user with the result
53+
event.respond(
54+
content: nil,
55+
embeds: [ answer_embed(answer, puzzle) ],
56+
ephemeral: true # Only the user sees this message
57+
)
58+
else
59+
# If the user has already answered, prevent them from changing their answer
60+
event.respond(
61+
content: "You have already answered this puzzle. You cannot change your answer.",
62+
ephemeral: true # Only the user sees this message
63+
)
64+
nil
65+
end
6066
end
6167

6268
private

app/models/answer.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
class Answer < ApplicationRecord
22
belongs_to :puzzle
33
belongs_to :user
4+
5+
validates :puzzle_id, uniqueness: { scope: [ :user_id, :server_id ] }
46
end

app/models/server.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
class Server < ApplicationRecord
2+
has_and_belongs_to_many :users, join_table: "users_servers"
23
has_one :channel
34
end

app/models/user.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class User < ApplicationRecord
2-
has_and_belongs_to_many :servers
3-
has_many :servers
2+
has_and_belongs_to_many :servers, join_table: "users_servers"
3+
has_many :answers
44

55
enum :role, admin: 0, member: 1
66
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddUniqueIndexToAnswers < ActiveRecord::Migration[8.0]
2+
def change
3+
add_index :answers, [ :puzzle_id, :user_id, :server_id ], unique: true, name: 'index_answers_on_puzzle_user_server'
4+
end
5+
end

db/schema.rb

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

db/seeds.rb

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,47 @@
1-
21
# db/seeds.rb
32

4-
# Create Puzzle records
5-
Puzzle.create!([
6-
{ 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." },
7-
{ 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." },
8-
{ 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." },
9-
{ 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." },
10-
{ 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." }
11-
])
3+
# ====== Create Puzzle records ======
4+
puzzles = [
5+
{
6+
question: "Ruby or Rails provided this method? Array.new(5) { |i| i * 2 }",
7+
answer: :ruby,
8+
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."
9+
},
10+
{
11+
question: "Ruby or Rails provided this method? File.open('log.txt', 'w') { |file| file.write('Hello, World!') }",
12+
answer: :ruby,
13+
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."
14+
},
15+
{
16+
question: "Ruby or Rails provided this method? render json: @user",
17+
answer: :rails,
18+
explanation: "`render json:` is a Rails method used to render a JSON response from a controller action."
19+
},
20+
{
21+
question: "Ruby or Rails provided this method? link_to 'Home', root_path",
22+
answer: :rails,
23+
explanation: "`link_to` is a Rails helper method that generates HTML links. `root_path` is a Rails path helper."
24+
},
25+
{
26+
question: "Ruby or Rails provided this method? params[:id]",
27+
answer: :rails,
28+
explanation: "`params[:id]` is used in Rails to fetch query parameters or URL parameters in controller actions."
29+
}
30+
]
31+
32+
puzzles.each do |p|
33+
Puzzle.find_or_create_by!(question: p[:question]) do |puzzle|
34+
puzzle.answer = p[:answer]
35+
puzzle.explanation = p[:explanation]
36+
end
37+
end
1238

13-
# Create a server
14-
Server.create!(server_id: 1179555097060061245, name: "OmbuTest")
39+
# ====== Create the Server ======
40+
server = Server.find_or_create_by!(server_id: 1179555097060061245) do |s|
41+
s.name = "OmbuTest"
42+
end
1543

16-
# Seed data for 10 users with answers
44+
# ====== Create Users and associate with Server ======
1745
users = [
1846
{ user_id: 101, username: "user1", role: "member" },
1947
{ user_id: 102, username: "user2", role: "member" },
@@ -28,16 +56,24 @@
2856
]
2957

3058
users.each do |user_data|
31-
user = User.create(user_id: user_data[:user_id], username: user_data[:username], role: user_data[:role])
59+
user = User.find_or_create_by!(user_id: user_data[:user_id]) do |u|
60+
u.username = user_data[:username]
61+
u.role = user_data[:role]
62+
end
63+
64+
# Associate user with the server if not already linked
65+
user.servers << server unless user.servers.include?(server)
3266

33-
# Randomly assign scores to answers (you can adjust as needed)
34-
3.times do
35-
Answer.create!(
36-
user_id: user.id,
37-
puzzle_id: Puzzle.all.sample.id,
38-
server_id: Server.first.id,
39-
choice: [ "ruby", "rails" ].sample,
40-
is_correct: [ true, false ].sample
41-
)
67+
# Seed random answers for this user if they have none
68+
if user.answers.where(server_id: server.id).empty?
69+
3.times do
70+
Answer.create!(
71+
user_id: user.id,
72+
puzzle_id: Puzzle.all.sample.id,
73+
server_id: server.id,
74+
choice: [ "ruby", "rails" ].sample,
75+
is_correct: [ true, false ].sample
76+
)
77+
end
4278
end
4379
end

0 commit comments

Comments
 (0)