Model Association (Rails 5 API)
up vote
3
down vote
favorite
I have a Character
model that has a CharClass
and ClassPerks
child.
Currently I am duplicating my logic a lot by manually assigning data.
My Character
index and create:
def index
@campaign = Campaign.find_by_id(params[:campaign_id])
@characters = @campaign.characters
render json: {
characters: @characters
}
end
def create
@campaign = Campaign.find_by_id(params[:campaign_id])
@charClass = CharClass.find_by_id(params[:character_char_class_id])
@character = @campaign.characters.new(character_params)
@character.char_class_id = params[:character_char_class_id]
if @character.save!
render status: 201, json: {
message: "Successfull added this character to the campaign!",
character_name: @character.character_name + ' the ' + @charClass.class_name,
character_class: @charClass.class_name,
character_level: @character.character_level,
character_experience: @character.character_experience,
character_gold: @character.character_gold,
character_perks: get_names(@character.character_perks),
character_image: @character.character_image
}
else
render status: 404, json: {
message: "Something went wrong: Check line 24 of the Character Controller"
}
end
end
I am manually assigning character_class
and character_image
despite both of these ALWAYS being the same based on their character_class
.
Inside of the character.rb
I am doing this to assign them post-create:
after_create :add_perks, :save_class
def add_perks
self.class_perks.each do |perk|
self.character_perks.create(class_perk_id: perk.id)
end
end
def save_class()
case self.char_class_id
when 1 # Mindthief
self.character_image = "https://gloomhavenil.files.wordpress.com/2017/12/11849117_616974988445216_217288420_n.jpg?w=480"
self.character_class = "Mindthief"
self.save
when 2 # Tinkerer
self.character_image = "http://www.cephalofair.com/wp-content/uploads/2015/04/Quatryl-Tinkerer.jpg"
self.character_class = "Tinkerer"
self.save
# when 'Sawbones'
# else
end
end
end
It is working, but I am unsure how to do this better/appropriately. I removed useless fields but you'll see below I have the relations set up appropriately.
create_table "char_classes", force: :cascade do |t|
t.string "class_name"
t.string "class_image"
t.string "class_perks"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "characters", force: :cascade do |t|
t.string "character_class"
t.string "character_image"
t.integer "char_class_id"
t.index ["campaign_id"], name: "index_characters_on_campaign_id"
t.index ["char_class_id"], name: "index_characters_on_char_class_id"
end
I can do Character.first.char_class.class_name
and I will get the appropriate result; so I am back to assuming this method I'm following is very incorrect.
ruby ruby-on-rails
bumped to the homepage by Community♦ 15 hours ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
3
down vote
favorite
I have a Character
model that has a CharClass
and ClassPerks
child.
Currently I am duplicating my logic a lot by manually assigning data.
My Character
index and create:
def index
@campaign = Campaign.find_by_id(params[:campaign_id])
@characters = @campaign.characters
render json: {
characters: @characters
}
end
def create
@campaign = Campaign.find_by_id(params[:campaign_id])
@charClass = CharClass.find_by_id(params[:character_char_class_id])
@character = @campaign.characters.new(character_params)
@character.char_class_id = params[:character_char_class_id]
if @character.save!
render status: 201, json: {
message: "Successfull added this character to the campaign!",
character_name: @character.character_name + ' the ' + @charClass.class_name,
character_class: @charClass.class_name,
character_level: @character.character_level,
character_experience: @character.character_experience,
character_gold: @character.character_gold,
character_perks: get_names(@character.character_perks),
character_image: @character.character_image
}
else
render status: 404, json: {
message: "Something went wrong: Check line 24 of the Character Controller"
}
end
end
I am manually assigning character_class
and character_image
despite both of these ALWAYS being the same based on their character_class
.
Inside of the character.rb
I am doing this to assign them post-create:
after_create :add_perks, :save_class
def add_perks
self.class_perks.each do |perk|
self.character_perks.create(class_perk_id: perk.id)
end
end
def save_class()
case self.char_class_id
when 1 # Mindthief
self.character_image = "https://gloomhavenil.files.wordpress.com/2017/12/11849117_616974988445216_217288420_n.jpg?w=480"
self.character_class = "Mindthief"
self.save
when 2 # Tinkerer
self.character_image = "http://www.cephalofair.com/wp-content/uploads/2015/04/Quatryl-Tinkerer.jpg"
self.character_class = "Tinkerer"
self.save
# when 'Sawbones'
# else
end
end
end
It is working, but I am unsure how to do this better/appropriately. I removed useless fields but you'll see below I have the relations set up appropriately.
create_table "char_classes", force: :cascade do |t|
t.string "class_name"
t.string "class_image"
t.string "class_perks"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "characters", force: :cascade do |t|
t.string "character_class"
t.string "character_image"
t.integer "char_class_id"
t.index ["campaign_id"], name: "index_characters_on_campaign_id"
t.index ["char_class_id"], name: "index_characters_on_char_class_id"
end
I can do Character.first.char_class.class_name
and I will get the appropriate result; so I am back to assuming this method I'm following is very incorrect.
ruby ruby-on-rails
bumped to the homepage by Community♦ 15 hours ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I have a Character
model that has a CharClass
and ClassPerks
child.
Currently I am duplicating my logic a lot by manually assigning data.
My Character
index and create:
def index
@campaign = Campaign.find_by_id(params[:campaign_id])
@characters = @campaign.characters
render json: {
characters: @characters
}
end
def create
@campaign = Campaign.find_by_id(params[:campaign_id])
@charClass = CharClass.find_by_id(params[:character_char_class_id])
@character = @campaign.characters.new(character_params)
@character.char_class_id = params[:character_char_class_id]
if @character.save!
render status: 201, json: {
message: "Successfull added this character to the campaign!",
character_name: @character.character_name + ' the ' + @charClass.class_name,
character_class: @charClass.class_name,
character_level: @character.character_level,
character_experience: @character.character_experience,
character_gold: @character.character_gold,
character_perks: get_names(@character.character_perks),
character_image: @character.character_image
}
else
render status: 404, json: {
message: "Something went wrong: Check line 24 of the Character Controller"
}
end
end
I am manually assigning character_class
and character_image
despite both of these ALWAYS being the same based on their character_class
.
Inside of the character.rb
I am doing this to assign them post-create:
after_create :add_perks, :save_class
def add_perks
self.class_perks.each do |perk|
self.character_perks.create(class_perk_id: perk.id)
end
end
def save_class()
case self.char_class_id
when 1 # Mindthief
self.character_image = "https://gloomhavenil.files.wordpress.com/2017/12/11849117_616974988445216_217288420_n.jpg?w=480"
self.character_class = "Mindthief"
self.save
when 2 # Tinkerer
self.character_image = "http://www.cephalofair.com/wp-content/uploads/2015/04/Quatryl-Tinkerer.jpg"
self.character_class = "Tinkerer"
self.save
# when 'Sawbones'
# else
end
end
end
It is working, but I am unsure how to do this better/appropriately. I removed useless fields but you'll see below I have the relations set up appropriately.
create_table "char_classes", force: :cascade do |t|
t.string "class_name"
t.string "class_image"
t.string "class_perks"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "characters", force: :cascade do |t|
t.string "character_class"
t.string "character_image"
t.integer "char_class_id"
t.index ["campaign_id"], name: "index_characters_on_campaign_id"
t.index ["char_class_id"], name: "index_characters_on_char_class_id"
end
I can do Character.first.char_class.class_name
and I will get the appropriate result; so I am back to assuming this method I'm following is very incorrect.
ruby ruby-on-rails
I have a Character
model that has a CharClass
and ClassPerks
child.
Currently I am duplicating my logic a lot by manually assigning data.
My Character
index and create:
def index
@campaign = Campaign.find_by_id(params[:campaign_id])
@characters = @campaign.characters
render json: {
characters: @characters
}
end
def create
@campaign = Campaign.find_by_id(params[:campaign_id])
@charClass = CharClass.find_by_id(params[:character_char_class_id])
@character = @campaign.characters.new(character_params)
@character.char_class_id = params[:character_char_class_id]
if @character.save!
render status: 201, json: {
message: "Successfull added this character to the campaign!",
character_name: @character.character_name + ' the ' + @charClass.class_name,
character_class: @charClass.class_name,
character_level: @character.character_level,
character_experience: @character.character_experience,
character_gold: @character.character_gold,
character_perks: get_names(@character.character_perks),
character_image: @character.character_image
}
else
render status: 404, json: {
message: "Something went wrong: Check line 24 of the Character Controller"
}
end
end
I am manually assigning character_class
and character_image
despite both of these ALWAYS being the same based on their character_class
.
Inside of the character.rb
I am doing this to assign them post-create:
after_create :add_perks, :save_class
def add_perks
self.class_perks.each do |perk|
self.character_perks.create(class_perk_id: perk.id)
end
end
def save_class()
case self.char_class_id
when 1 # Mindthief
self.character_image = "https://gloomhavenil.files.wordpress.com/2017/12/11849117_616974988445216_217288420_n.jpg?w=480"
self.character_class = "Mindthief"
self.save
when 2 # Tinkerer
self.character_image = "http://www.cephalofair.com/wp-content/uploads/2015/04/Quatryl-Tinkerer.jpg"
self.character_class = "Tinkerer"
self.save
# when 'Sawbones'
# else
end
end
end
It is working, but I am unsure how to do this better/appropriately. I removed useless fields but you'll see below I have the relations set up appropriately.
create_table "char_classes", force: :cascade do |t|
t.string "class_name"
t.string "class_image"
t.string "class_perks"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "characters", force: :cascade do |t|
t.string "character_class"
t.string "character_image"
t.integer "char_class_id"
t.index ["campaign_id"], name: "index_characters_on_campaign_id"
t.index ["char_class_id"], name: "index_characters_on_char_class_id"
end
I can do Character.first.char_class.class_name
and I will get the appropriate result; so I am back to assuming this method I'm following is very incorrect.
ruby ruby-on-rails
ruby ruby-on-rails
edited Apr 12 at 0:19
Jamal♦
30.2k11115226
30.2k11115226
asked Apr 12 at 0:08
DNorthrup
1855
1855
bumped to the homepage by Community♦ 15 hours ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 15 hours ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
You need to use ActiveModelSerializers (AMS) to serialize your json responses based upon the instances of your class.
class CampaignsController < ApplicationController
def index
render json: { characters: campaign.characters }
end
def create
@character = campaign.characters.new(character_params.merge(char_class_id: char_class.id))
if @character.save!
render json: @character, serializer: CharacterSerializer, status: 201 # This should automatically be formatted by AMS
else
not_found('Something went wrong: Check line 24 of the Character Controller')
end
end
private
def campaign
@campaign ||= Campaign.find_by_id(params[:campaign_id])
end
def char_class
@charClass ||= CharClass.find_by_id(params[:character_char_class_id])
end
end
This is how you AMS class for Character class should look like
class CharacterSerializer < ActiveModel::Serializer
attributes :message, :character_name, :character_class, :character_level, :character_experience, :character_gold, :character_perks, :character_image
def message
'Successfull added this character to the campaign!'
end
def character_name
return object.character_name + ' the ' + character_class # check the associations
end
def character_class
object.charClass.class_name
end
def character_perks
# Unsure what this get names methods does so im leaving it for you to refactor
get_names(object.character_perks),
end
end
Also add this to your ApplicationController
class ApplicationController < ActionController::Base
# Add this to your application controller
def not_found(message = nil)
render json: { message }, status: 404
end
end
I'll update the refactored model class based upon your info soon. Hope this helps for now.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
You need to use ActiveModelSerializers (AMS) to serialize your json responses based upon the instances of your class.
class CampaignsController < ApplicationController
def index
render json: { characters: campaign.characters }
end
def create
@character = campaign.characters.new(character_params.merge(char_class_id: char_class.id))
if @character.save!
render json: @character, serializer: CharacterSerializer, status: 201 # This should automatically be formatted by AMS
else
not_found('Something went wrong: Check line 24 of the Character Controller')
end
end
private
def campaign
@campaign ||= Campaign.find_by_id(params[:campaign_id])
end
def char_class
@charClass ||= CharClass.find_by_id(params[:character_char_class_id])
end
end
This is how you AMS class for Character class should look like
class CharacterSerializer < ActiveModel::Serializer
attributes :message, :character_name, :character_class, :character_level, :character_experience, :character_gold, :character_perks, :character_image
def message
'Successfull added this character to the campaign!'
end
def character_name
return object.character_name + ' the ' + character_class # check the associations
end
def character_class
object.charClass.class_name
end
def character_perks
# Unsure what this get names methods does so im leaving it for you to refactor
get_names(object.character_perks),
end
end
Also add this to your ApplicationController
class ApplicationController < ActionController::Base
# Add this to your application controller
def not_found(message = nil)
render json: { message }, status: 404
end
end
I'll update the refactored model class based upon your info soon. Hope this helps for now.
add a comment |
up vote
0
down vote
You need to use ActiveModelSerializers (AMS) to serialize your json responses based upon the instances of your class.
class CampaignsController < ApplicationController
def index
render json: { characters: campaign.characters }
end
def create
@character = campaign.characters.new(character_params.merge(char_class_id: char_class.id))
if @character.save!
render json: @character, serializer: CharacterSerializer, status: 201 # This should automatically be formatted by AMS
else
not_found('Something went wrong: Check line 24 of the Character Controller')
end
end
private
def campaign
@campaign ||= Campaign.find_by_id(params[:campaign_id])
end
def char_class
@charClass ||= CharClass.find_by_id(params[:character_char_class_id])
end
end
This is how you AMS class for Character class should look like
class CharacterSerializer < ActiveModel::Serializer
attributes :message, :character_name, :character_class, :character_level, :character_experience, :character_gold, :character_perks, :character_image
def message
'Successfull added this character to the campaign!'
end
def character_name
return object.character_name + ' the ' + character_class # check the associations
end
def character_class
object.charClass.class_name
end
def character_perks
# Unsure what this get names methods does so im leaving it for you to refactor
get_names(object.character_perks),
end
end
Also add this to your ApplicationController
class ApplicationController < ActionController::Base
# Add this to your application controller
def not_found(message = nil)
render json: { message }, status: 404
end
end
I'll update the refactored model class based upon your info soon. Hope this helps for now.
add a comment |
up vote
0
down vote
up vote
0
down vote
You need to use ActiveModelSerializers (AMS) to serialize your json responses based upon the instances of your class.
class CampaignsController < ApplicationController
def index
render json: { characters: campaign.characters }
end
def create
@character = campaign.characters.new(character_params.merge(char_class_id: char_class.id))
if @character.save!
render json: @character, serializer: CharacterSerializer, status: 201 # This should automatically be formatted by AMS
else
not_found('Something went wrong: Check line 24 of the Character Controller')
end
end
private
def campaign
@campaign ||= Campaign.find_by_id(params[:campaign_id])
end
def char_class
@charClass ||= CharClass.find_by_id(params[:character_char_class_id])
end
end
This is how you AMS class for Character class should look like
class CharacterSerializer < ActiveModel::Serializer
attributes :message, :character_name, :character_class, :character_level, :character_experience, :character_gold, :character_perks, :character_image
def message
'Successfull added this character to the campaign!'
end
def character_name
return object.character_name + ' the ' + character_class # check the associations
end
def character_class
object.charClass.class_name
end
def character_perks
# Unsure what this get names methods does so im leaving it for you to refactor
get_names(object.character_perks),
end
end
Also add this to your ApplicationController
class ApplicationController < ActionController::Base
# Add this to your application controller
def not_found(message = nil)
render json: { message }, status: 404
end
end
I'll update the refactored model class based upon your info soon. Hope this helps for now.
You need to use ActiveModelSerializers (AMS) to serialize your json responses based upon the instances of your class.
class CampaignsController < ApplicationController
def index
render json: { characters: campaign.characters }
end
def create
@character = campaign.characters.new(character_params.merge(char_class_id: char_class.id))
if @character.save!
render json: @character, serializer: CharacterSerializer, status: 201 # This should automatically be formatted by AMS
else
not_found('Something went wrong: Check line 24 of the Character Controller')
end
end
private
def campaign
@campaign ||= Campaign.find_by_id(params[:campaign_id])
end
def char_class
@charClass ||= CharClass.find_by_id(params[:character_char_class_id])
end
end
This is how you AMS class for Character class should look like
class CharacterSerializer < ActiveModel::Serializer
attributes :message, :character_name, :character_class, :character_level, :character_experience, :character_gold, :character_perks, :character_image
def message
'Successfull added this character to the campaign!'
end
def character_name
return object.character_name + ' the ' + character_class # check the associations
end
def character_class
object.charClass.class_name
end
def character_perks
# Unsure what this get names methods does so im leaving it for you to refactor
get_names(object.character_perks),
end
end
Also add this to your ApplicationController
class ApplicationController < ActionController::Base
# Add this to your application controller
def not_found(message = nil)
render json: { message }, status: 404
end
end
I'll update the refactored model class based upon your info soon. Hope this helps for now.
edited Apr 12 at 4:12
answered Apr 12 at 4:00
Aniket Rao
1012
1012
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191831%2fmodel-association-rails-5-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown