patternrubyrailsMinor
Seed a database
Viewed 0 times
databaseseedstackoverflow
Problem
I'm looking for advice / best practice to avoid doing a deeply nested set of
Short version - without specific examples
My basic pattern is 1 .. n
Where the issue exists is I have two additional, unrelated relationships which should populate at each step back at each step & potentially 4 or 5 that need to populate.
Long version - with specific examples
Basic setup: each game is a campaign. Each campaign will have players, each player will have a country (each country also has a join table back to the campaign), each country a state...
I'm hoping there's an elegant way of doing this instead without using too many object chains (".")'s, but perfectly happy to do so if that's the only way.
Originally, I was doing
I also had tried using the same join tables with models using has_many, through: for this pattern ...
My models are a bit of a mess but all present ...
There are several primary tables & a join table between each (including a belongs_to matching the has_many's pointed at it from other files)
user.rb
campaign.rb
IF/THEN statements in Rails. The intention is to seed a database.Short version - without specific examples
My basic pattern is 1 .. n
IF(1st_object_exists) THEN
2nd_object = 1st_object.relationship.create!(args)
IF (2nd_object) THEN
3rd_object ... so on & so forth down 9 levels ...
END
ENDWhere the issue exists is I have two additional, unrelated relationships which should populate at each step back at each step & potentially 4 or 5 that need to populate.
Long version - with specific examples
Basic setup: each game is a campaign. Each campaign will have players, each player will have a country (each country also has a join table back to the campaign), each country a state...
I'm hoping there's an elegant way of doing this instead without using too many object chains (".")'s, but perfectly happy to do so if that's the only way.
Originally, I was doing
Campaign.Players.Countries.create!(args), which errors with not valid method for Countries or Players until I eliminate one or the other. Eliminating this leaves me seeding the relationship value for the other has_many else where though...I also had tried using the same join tables with models using has_many, through: for this pattern ...
user = User.first
if(user) then
campaign = user.campaigns.create!(args)
if(campaign) then
new_player = game_instance.players.create!(args)
if(new_player) then
new_country = new_player.countries.create!(args)
if(new_country) then
new_country.states.create!(args)
end
end
end
endMy models are a bit of a mess but all present ...
There are several primary tables & a join table between each (including a belongs_to matching the has_many's pointed at it from other files)
user.rb
has_many :userplays
has_many :players, through: :userplays
has_many :usercamps
has_many :campaigns, through: :usercampscampaign.rb
Solution
On a technical note
What I usually do is put it in a separate method and use an early return:
You can combine the return as follows:
Or even
But I prefer not to use this programming style
-- Update 1
To clarify by
create! will always return a valid object (or raise an exception)What I usually do is put it in a separate method and use an early return:
user = User.first
return unless user
campaign = user.campaigns.create!(args)
return unless campaign
new_player = game_instance.players.create!(args)
return unless new_player
new_country = new_player.countries.create!(args)
return unless new_county
new_country.states.create!(args)You can combine the return as follows:
user = User.first || return
campaign = user.campaigns.create!(args) || return
new_player = game_instance.players.create!(args) || return
new_country = new_player.countries.create!(args) || return
new_country.states.create!(args)Or even
campaign = User.first &. campaigns.create!(args)
return unless campaign
game_instance.players.create!(args) &.
countries.create!(args) &.
states.create!(args)But I prefer not to use this programming style
-- Update 1
To clarify by
it I mean these lines of code. Depending on what you do following this you might want to not put all the code in the same place.Code Snippets
user = User.first
return unless user
campaign = user.campaigns.create!(args)
return unless campaign
new_player = game_instance.players.create!(args)
return unless new_player
new_country = new_player.countries.create!(args)
return unless new_county
new_country.states.create!(args)user = User.first || return
campaign = user.campaigns.create!(args) || return
new_player = game_instance.players.create!(args) || return
new_country = new_player.countries.create!(args) || return
new_country.states.create!(args)campaign = User.first &. campaigns.create!(args)
return unless campaign
game_instance.players.create!(args) &.
countries.create!(args) &.
states.create!(args)Context
StackExchange Code Review Q#156640, answer score: 2
Revisions (0)
No revisions yet.