So here was the problem: I had a single deck of cards and I wanted to remember the card(s) I pulled out at any given time, even AFTER putting the card(s) back in the deck.
My original thought was that this was a backend issue. A Draw has_many Cards, and a Card belongs_to a Draw.
class Draw < ApplicationRecord
has_many :cards
end
class Card < ApplicationRecord
belongs_to :draw
end
create_table "draws", force: :cascade do |t|
t.string "card"
end
create_table "cards", force: :cascade do |t|
t.string "name"
t.integer "draw_id"
end
But what if I didn't want a single Card to be permanently tied to a Draw? What if I wanted that relationship, but also wanted it to part of other Draws? So I added 'optional' to the relationship.
class Card < ApplicationRecord
belongs_to :draw, optional: true
end
Which was closer... but it still made me uncomfortable thinking that the pristine deck of Cards sitting in my database would ever have a relationship with a single Draw. Enter React-Redux.
My thought was that a Draw doesn't need a specific Card, exactly, it needs the ID of a Card. So the first thing I did was change the schema.
create_table "draws", force: :cascade do |t|
t.integer "card"
end
Then on my frontend I created a method that give me a random number based on the length of an array and convert that number to an index in the array.
getRandomItem = (arr) => {
const randomIndex = Math.floor(Math.random) * arr.length);
const item = arr[randomIndex];
return item.id;
}
The, when submitting my form for a new Draw, I could call on this method and for the argument use the Card Array.
handleSubmit = (e) =>{
e.preventDefault()
let formData = {
card: this.getRandomItem(this.props.cards)
}
this.props.createDraws(formData)
}
This populated my Draw instance on the backend with a number that I saved as Draw.card. Then, when rendering a Draw back on the frontend I could just access that number and find the Card associated with it.
const Draw = props =>{
let draw = props.draws.draws[props.match.params.id - 1]
return(
<div>
Card Name: {draw && (props.cards.length > 0) ? <props.cards[draw.card - 1].name} : null
</div>
)
}
And there you have it! A faux has_many relationship built almost entirely on the frontend of my app. Pretty sneaky React. Pretty sneaky.
Top comments (0)