How to call a class method in \lib from model in rails? -
i'm trying generate stats character created form. user inputs name, race, class, alignment, , whether or not stats generated randomly, or prioritized (values being assigned highest lowest). form works flawlessly, can see output in view.
what trying call method class in /lib in model generate stats; however, keep getting following error (i can't post pictures):
nomethoderror in characterscontroller#create undefined method `[]' nil:nilclass extracted source (around line #14): 12 before_save 13 generate_stats 14 self.strength = @character_stats[:strength] 15 self.dexterity = @character_stats[:dexterity] 16 self.constitution = @character_stats[:constitution] 17 self.intelligence = @character_stats[:intelligence] here copy of of code:
in controllers\characters_controller.rb
class characterscontroller < applicationcontroller def create @character = character.new(character_info_params) @character.name = params[:character][:name].capitalize @character.alignment = "#{params[:character][:alignment_lr]} #{params[:character][:alignment_ud]}" if @character.save redirect_to @character else render 'new' end end private def character_info_params params.require(:character).permit(:name, :race, :class_, :alignment) end end in models\character.rb
class character < activerecord::base require 'random_stats_generator' attr_accessor :rand_stat_gen def generate_stats if @rand_stat_gen == true @character_stats_inst = randomstatgenerator.new @character_stats = @character_stats_inst.generate end end before_save generate_stats self.strength = @character_stats[:strength] self.dexterity = @character_stats[:dexterity] self.constitution = @character_stats[:constitution] self.intelligence = @character_stats[:intelligence] self.wisdom = @character_stats[:wisdom] self.charisma = @character_stats[:charisma] end #validation passed point end in initializers\stat_builders.rb
require "./lib/random_stat_generator.rb" in lib/random_stat_generator.rb
class randomstatgenerator def initialize @strength = :strength @dexterity = :dexterity @constitution = :constitution @intelligence = :intelligence @wisdom = :wisdom @charisma = :charisma @character_stats = hashwithindifferentaccess.new() end def self.generate roll_stats end def roll(stat) @roll_value_1 = (1 + (rand(6))) @roll_value_2 = (1 + (rand(6))) @roll_value_3 = (1 + (rand(6))) @roll_value_4 = (1 + (rand(6))) @roll_array = [@roll_value_1,@roll_value_2,@roll_value_3,@roll_value_4] @roll_array = @roll_array.sort_by {|x| x } @roll_array = @roll_array.reverse stat = @roll_array[0] + @roll_array[1] + @roll_array[2] end def roll_stats @strength = roll(@strength) @dexterity = roll(@dexterity) @constitution = roll(@constitution) @intelligence = roll(@intelligence) @wisdom = roll(@wisdom) @charisma = roll(@charisma) @character_stats[:strength] = @strength @character_stats[:dexterity] = @dexterity @character_stats[:constitution] = @constitution @character_stats[:intelligence] = @intelligence @character_stats[:wisdom] = @wisdom @character_stats[:charisma] = @charisma return @character_stats end end to me, looks method isn't returning anything, or isn't being called @ all.
i've tried lot of solutions i've come across online, none of them working. there may things don't make sense left on these solutions. i'm starting rails, i'm still trying used everything.
thanks lot help.
ruby has powerful functions manipulating both hashes , arrays. typing out duplicate assignments like:
self.strength = @character_stats[:strength] self.dexterity = @character_stats[:dexterity] self.constitution = @character_stats[:constitution] is pretty dull. instead can rewrite methods pass hashes around.
class randomstatgenerator # constant containing stats want generate. stats = [:strength, :dexterity, :constitution, :intelligence, :wisdom, :charisma] # create hash random roll values each stat def self.roll_stats # kind of scary looking creates # hash array of keys hash[stats.map {|k| [k, self.roll ] } ] end private def self.roll # create array 4 elements (nil) ary = array.new(4) # replace nil value random value 1-6 ary = ary.map (1 + (rand(6))) end # sort , drop lowest roll. return sum of rolls. ary.sort.drop(1).sum # ruby ninja writes array.new(4).map { 1 + rand(6) }.sort.drop(1).sum end end output:
irb(main):032:0> randomstatgenerator.roll_stats => {:strength=>14, :dexterity=>14, :constitution=>14, :intelligence=>13, :wisdom=>10, :charisma=>9} but if don't intend create instances of class, should use module instead.
rails models can either created hash or can replace values hash:
character.new(randomstatgenerator.roll_stats) @character.assign_attributes(randomstatgenerator.roll_stats) so can use in character#generate_stats:
def generate_stats assign_attributes(randomstatgenerator.roll_stats) end you should use activemodel callbacks extreme prejudice. quite challenge regulate in application , when in model lifetime. since before_save runs after validations means validations validates_presence_of :constitution fail.
in case might better in controller or use:
before_validation :generate_stats, if: -> { new_record? && @rand_stat_gen }
Comments
Post a Comment