ru.Bee 2.7.4 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/db/test.db +0 -0
- data/lib/rubee/cli/bee_knowledge.json +1 -1
- data/lib/rubee/cli/db.rb +9 -3
- data/lib/rubee/configuration.rb +14 -2
- data/lib/rubee/generator.rb +2 -1
- data/lib/rubee.rb +1 -1
- data/lib/tests/rubee_generator_test.rb +40 -17
- data/readme.md +171 -76
- metadata +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.1.0","idf":{"producte":2.727220948090484,"ready":3.1972245773362196,"take":4.113515309210374,"look":4.113515309210374,"demo":3.70805020110221,"site":3.70805020110221,"full":2.504077396776274,"documentate":3.0149030205422647,"http":2.2417131323087833,"dedyn":3.1972245773362196,"want":3.0149030205422647,"explore":3.4203681286504293,"built":3.0149030205422647,"github":4.113515309210374,"com":2.408767216971949,"nucleom42":4.113515309210374,"stres":4.113515309210374,"test":1.9734491457141037,"code":1.1431008436406733,"wrk":4.113515309210374,"c100":4.113515309210374,"d30":4.113515309210374,"doc":4.113515309210374,"running":2.727220948090484,"30":4.113515309210374,"thread":4.113515309210374,"100":4.113515309210374,"connection":3.4203681286504293,"stat":4.113515309210374,"avg":4.113515309210374,"stdev":4.113515309210374,"max":3.70805020110221,"latency":4.113515309210374,"304":4.113515309210374,"95m":4.113515309210374,"22m":4.113515309210374,"551":4.113515309210374,"86m":4.113515309210374,"req":4.113515309210374,"sec":4.113515309210374,"280":4.113515309210374,"9721":4.113515309210374,"request":3.70805020110221,"02":4.113515309210374,"11mb":4.113515309210374,"read":3.4203681286504293,"323":4.113515309210374,"transfer":4.113515309210374,"140":4.113515309210374,"07kb":4.113515309210374,"short":3.70805020110221,"output":3.0149030205422647,"explanate":4.113515309210374,"324":4.113515309210374,"average":4.113515309210374,"305":4.113515309210374,"total":3.4203681286504293,"handl":4.113515309210374,"721":4.113515309210374,"hardware":4.113515309210374,"raspberry":4.113515309210374,"single":2.727220948090484,"board":4.113515309210374,"computer":4.113515309210374,"server":2.09861228866811,"app":2.09861228866811,"host":3.4203681286504293,"nginx":4.113515309210374,"demonstrates":4.113515309210374,"efficient":3.70805020110221,"architecture":4.113515309210374,"suitability":4.113515309210374,"lightweight":3.70805020110221,"deployment":4.113515309210374,"even":4.113515309210374,"low":3.4203681286504293,"power":3.70805020110221,"comparison":4.113515309210374,"here":3.70805020110221,"web":4.113515309210374,"framework":3.4203681286504293,"ruby":2.504077396776274,"evaluate":4.113515309210374,"choice":4.113515309210374,"disclaimer":4.113515309210374,"bas":3.1972245773362196,"generic":4.113515309210374,"subjective":4.113515309210374,"informate":4.113515309210374,"available":2.6094379124341005,"internet":3.70805020110221,"not":2.6094379124341005,"real":4.113515309210374,"benchmark":4.113515309210374,"aim":4.113515309210374,"giving":4.113515309210374,"general":4.113515309210374,"idea":3.4203681286504293,"differences":4.113515309210374,"between":4.113515309210374,"intend":4.113515309210374,"direct":2.860752340715006,"features":4.113515309210374,"minimal":4.113515309210374,"footprint":4.113515309210374,"focus":4.113515309210374,"serving":4.113515309210374,"applicate":3.4203681286504293,"modular":3.4203681286504293,"approach":4.113515309210374,"applicat":3.1972245773362196,"development":2.2417131323087833,"build":3.0149030205422647,"monolith":4.113515309210374,"ease":3.70805020110221,"attaching":4.113515309210374,"many":3.0149030205422647,"subproject":3.4203681286504293,"ne":2.860752340715006,"contract":3.70805020110221,"driven":4.113515309210374,"define":3.0149030205422647,"api":3.1972245773362196,"simple":3.70805020110221,"declarative":4.113515309210374,"way":4.113515309210374,"then":3.0149030205422647,"generate":2.09861228866811,"all":2.167605160155061,"boilerplate":4.113515309210374,"fast":4.113515309210374,"optimiz":4.113515309210374,"spe":3.70805020110221,"providing":4.113515309210374,"quick":4.113515309210374,"responses":3.70805020110221,"rack":3.1972245773362196,"easy":4.113515309210374,"integrate":4.113515309210374,"databases":3.1972245773362196,"support":2.2417131323087833,"sqlite3":3.70805020110221,"postgresql":3.70805020110221,"mysql":4.113515309210374,"more":3.4203681286504293,"sequel":2.860752340715006,"gem":2.727220948090484,"view":2.2417131323087833,"json":2.3217558399823197,"erb":2.727220948090484,"plain":3.70805020110221,"html":3.70805020110221,"box":3.4203681286504293,"react":2.860752340715006,"first":2.504077396776274,"clas":1.8622235106038794,"engine":3.1972245773362196,"bundlable":4.113515309210374,"charge":4.113515309210374,"any":2.3217558399823197,"update":2.504077396776274,"effortles":4.113515309210374,"bundler":3.70805020110221,"orm":3.4203681286504293,"agnostic":4.113515309210374,"model":1.8109302162163288,"native":4.113515309210374,"object":2.408767216971949,"but":4.113515309210374,"them":4.113515309210374,"blueprint":4.113515309210374,"data":2.727220948090484,"source":4.113515309210374,"authenticatable":4.113515309210374,"easi":4.113515309210374,"add":2.167605160155061,"jwt":3.1972245773362196,"authenticat":3.0149030205422647,"controller":2.2417131323087833,"acte":2.860752340715006,"hook":2.860752340715006,"logic":3.0149030205422647,"before":2.504077396776274,"after":2.727220948090484,"around":3.70805020110221,"testable":4.113515309210374,"select":4.113515309210374,"belov":4.113515309210374,"minitest":4.113515309210374,"asyncable":3.1972245773362196,"plug":3.70805020110221,"async":3.1972245773362196,"adapter":3.1972245773362196,"popular":4.113515309210374,"background":3.1972245773362196,"job":3.1972245773362196,"console":3.70805020110221,"start":1.9734491457141037,"interactive":2.860752340715006,"reload":3.1972245773362196,"f":4.113515309210374,"schedule":4.113515309210374,"proces":3.4203681286504293,"preferr":4.113515309210374,"stack":3.70805020110221,"websocket":3.1972245773362196,"serve":4.113515309210374,"handle":4.113515309210374,"logger":3.70805020110221,"installate":4.113515309210374,"install":2.504077396776274,"create":2.09861228866811,"project":3.1972245773362196,"my_project":4.113515309210374,"dependency":2.860752340715006,"prerequisites":3.4203681286504293,"higher":4.113515309210374,"recommend":3.4203681286504293,"bundle":3.4203681286504293,"default":2.167605160155061,"port":3.4203681286504293,"7000":3.4203681286504293,"start_dev":2.860752340715006,"dev":2.860752340715006,"starting":3.0149030205422647,"version":2.860752340715006,"yjit":4.113515309210374,"compiler":4.113515309210374,"boost":4.113515309210374,"jit":4.113515309210374,"opte":4.113515309210374,"environment":2.6094379124341005,"too":4.113515309210374,"open":3.0149030205422647,"browser":3.4203681286504293,"localhost":2.727220948090484,"specify":4.113515309210374,"specific":2.408767216971949,"file":2.3217558399823197,"user_model_test":3.70805020110221,"user":1.9734491457141037,"line":3.1972245773362196,"draw":2.6094379124341005,"routes":2.408767216971949,"router":2.504077396776274,"apples":2.6094379124341005,"index":2.408767216971949,"name":2.3217558399823197,"apple":3.0149030205422647,"attributes":2.727220948090484,"type":2.167605160155061,"primary":3.0149030205422647,"colour":3.0149030205422647,"string":2.727220948090484,"weight":3.0149030205422647,"integer":3.0149030205422647,"creat":2.860752340715006,"datetime":3.0149030205422647,"updat":2.727220948090484,"end":1.8109302162163288,"files":3.0149030205422647,"apples_controller":3.4203681286504293,"respective":4.113515309210374,"apples_index":3.4203681286504293,"render":2.860752340715006,"act":4.113515309210374,"create_apples":3.1972245773362196,"database":2.2417131323087833,"migrate":2.727220948090484,"table":3.70805020110221,"initial":3.4203681286504293,"fill":3.4203681286504293,"generat":3.0149030205422647,"again":4.113515309210374,"find":3.1972245773362196,"snapshot":4.113515309210374,"schema":3.4203681286504293,"structure":3.1972245773362196,"constant":4.113515309210374,"print":3.70805020110221,"latest":3.70805020110221,"cli":3.4203681286504293,"email":2.3217558399823197,"varchar":4.113515309210374,"255":4.113515309210374,"password":2.408767216971949,"account":3.70805020110221,"addres":4.113515309210374,"user_id":3.4203681286504293,"post":2.727220948090484,"comment_id":3.4203681286504293,"comment":3.4203681286504293,"text":3.0149030205422647,"nullable":4.113515309210374,"foreign":3.4203681286504293,"key":2.727220948090484,"delete":3.4203681286504293,"no_acte":4.113515309210374,"dropping":4.113515309210374,"tables":4.113515309210374,"handy":4.113515309210374,"during":4.113515309210374,"careful":4.113515309210374,"pas":3.1972245773362196,"desir":3.4203681286504293,"rack_env":3.4203681286504293,"env":2.3217558399823197,"drop_tables":4.113515309210374,"drop":4.113515309210374,"dropp":4.113515309210374,"company":4.113515309210374,"company_client":4.113515309210374,"client":3.1972245773362196,"services":4.113515309210374,"serializ":4.113515309210374,"whatever":4.113515309210374,"form":4.113515309210374,"requir":2.860752340715006,"rendering":4.113515309210374,"memory":3.70805020110221,"applescontroller":3.70805020110221,"def":2.2417131323087833,"new":2.408767216971949,"r":4.113515309210374,"1lb":4.113515309210374,"green":4.113515309210374,"param":3.4203681286504293,"response_with":2.6094379124341005,"response":2.408767216971949,"serializable":4.113515309210374,"module":3.1972245773362196,"includ":4.113515309210374,"target":3.70805020110221,"include":2.167605160155061,"attr_accessor":3.70805020110221,"attr":3.70805020110221,"accessor":3.70805020110221,"turn":4.113515309210374,"extending":4.113515309210374,"sequelobject":3.4203681286504293,"already":4.113515309210374,"charg":3.4203681286504293,"llo":3.70805020110221,"543":3.70805020110221,"save":3.4203681286504293,"record":3.70805020110221,"irb":3.4203681286504293,"main":2.727220948090484,"018":3.70805020110221,"true":2.504077396776274,"value":3.4203681286504293,"019":3.70805020110221,"check":3.70805020110221,"whether":3.70805020110221,"persist":3.4203681286504293,"016":3.70805020110221,"false":3.0149030205422647,"011":3.70805020110221,"last":3.1972245773362196,"012":3.70805020110221,"014":3.70805020110221,"unpersist":3.70805020110221,"refresh":3.70805020110221,"assign":3.70805020110221,"without":3.1972245773362196,"persisting":3.70805020110221,"008":3.70805020110221,"assign_attributes":3.70805020110221,"ok23":3.70805020110221,"123":2.727220948090484,"scop":3.70805020110221,"field":3.4203681286504293,"005":3.70805020110221,"001":3.70805020110221,"002":3.70805020110221,"003":3.70805020110221,"004":3.70805020110221,"destroy":3.70805020110221,"relat":3.1972245773362196,"021":3.70805020110221,"cascade":3.70805020110221,"initialize":3.1972245773362196,"instance":3.70805020110221,"subsequent":3.70805020110221,"persistence":3.4203681286504293,"020":3.70805020110221,"find_or_new":3.70805020110221,"022":3.70805020110221,"023":3.70805020110221,"one":2.408767216971949,"destroy_all":3.70805020110221,"complex":3.70805020110221,"query":3.70805020110221,"chain":3.70805020110221,"serialize":3.70805020110221,"result":3.70805020110221,"back":3.70805020110221,"dataset":3.4203681286504293,"join":3.70805020110221,"009":3.70805020110221,"010":3.70805020110221,"since":3.70805020110221,"method":2.504077396776274,"order":3.70805020110221,"limit":3.70805020110221,"offset":3.70805020110221,"owns_many":3.70805020110221,"own":3.0149030205422647,"owns_one":3.70805020110221,"paginate":3.70805020110221,"page":3.70805020110221,"per_page":3.70805020110221,"per":3.70805020110221,"pagination_meta":3.70805020110221,"meta":3.70805020110221,"current_page":3.70805020110221,"current":3.70805020110221,"total_count":3.70805020110221,"count":3.70805020110221,"first_page":3.70805020110221,"last_page":3.70805020110221,"prev":3.70805020110221,"nil":3.70805020110221,"next":3.1972245773362196,"base":2.09861228866811,"initiate":4.113515309210374,"015":4.113515309210374,"postgres":4.113515309210374,"sqlite":2.727220948090484,"ful":4.113515309210374,"potential":4.113515309210374,"us":3.4203681286504293,"gemfile":3.0149030205422647,"url":2.408767216971949,"each":3.4203681286504293,"config":2.408767216971949,"base_configurate":2.6094379124341005,"configurate":2.408767216971949,"setup":2.408767216971949,"database_url":2.860752340715006,"configure":2.6094379124341005,"5432":4.113515309210374,"db_password":4.113515309210374,"suite":4.113515309210374,"ensure":4.113515309210374,"initializ":4.113515309210374,"init":3.70805020110221,"ensures":4.113515309210374,"run":4.113515309210374,"issue":3.1972245773362196,"write":3.0149030205422647,"locking":3.70805020110221,"resolv":3.70805020110221,"tune":3.70805020110221,"retry":3.4203681286504293,"parameter":3.4203681286504293,"need":2.860752340715006,"db_max_retry":4.113515309210374,"disable":4.113515309210374,"increase":4.113515309210374,"db_retry_delay":4.113515309210374,"delay":4.113515309210374,"db_busy_timeout":4.113515309210374,"busy":4.113515309210374,"timeout":4.113515309210374,"1000":4.113515309210374,"millisecond":4.113515309210374,"raising":4.113515309210374,"error":2.860752340715006,"automatical":3.4203681286504293,"dbtool":4.113515309210374,"with_retry":4.113515309210374,"insert":4.113515309210374,"routing":3.0149030205422647,"uses":4.113515309210374,"explicit":3.70805020110221,"match":3.70805020110221,"denot":4.113515309210374,"route":2.860752340715006,"path":3.0149030205422647,"a_key":4.113515309210374,"somewhere":4.113515309210374,"patch":3.4203681286504293,"put":3.4203681286504293,"head":3.70805020110221,"connect":3.70805020110221,"option":2.504077396776274,"trace":3.70805020110221,"every":3.0149030205422647,"follow":3.70805020110221,"http_method":3.70805020110221,"optional":3.1972245773362196,"namespace":3.4203681286504293,"defining":3.70805020110221,"unique":3.70805020110221,"trait":3.70805020110221,"other":3.70805020110221,"attribute":3.4203681286504293,"types":3.70805020110221,"descripte":3.70805020110221,"quantity":3.70805020110221,"date":3.70805020110221,"modifi":3.70805020110221,"exist":3.70805020110221,"time":3.0149030205422647,"active":3.70805020110221,"boolean":3.70805020110221,"hash":3.4203681286504293,"bigint":3.70805020110221,"price":3.70805020110221,"decimal":3.70805020110221,"item_id":3.70805020110221,"item":3.70805020110221,"foreign_key":3.70805020110221,"item_id_index":3.70805020110221,"item_id_unique":3.70805020110221,"carry":3.70805020110221,"definite":3.70805020110221,"size":3.70805020110221,"fix":3.70805020110221,"get":3.4203681286504293,"translat":3.70805020110221,"long":3.70805020110221,"on":3.4203681286504293,"defin":3.1972245773362196,"gen":2.727220948090484,"generates":3.4203681286504293,"attach":3.70805020110221,"folder":3.70805020110221,"mvc":3.70805020110221,"namespacing":3.70805020110221,"while":3.70805020110221,"still":3.70805020110221,"sharing":3.70805020110221,"admin":3.70805020110221,"admin_routes":3.70805020110221,"cabbages":3.70805020110221,"cabbage":3.70805020110221,"mandatory":3.4203681286504293,"command":2.408767216971949,"cabbages_controller":3.70805020110221,"cabbages_index":3.70805020110221,"create_cabbages":3.70805020110221,"content":3.70805020110221,"cabbagescontroller":3.70805020110221,"basecontroller":3.0149030205422647,"templates":3.70805020110221,"layout":3.70805020110221,"parent":3.70805020110221,"template":3.70805020110221,"child":3.70805020110221,"inside":3.4203681286504293,"feel":3.1972245773362196,"free":3.1972245773362196,"custom":3.0149030205422647,"cs":3.70805020110221,"there":3.70805020110221,"welcome_controller":3.4203681286504293,"welcome":3.1972245773362196,"welcomecontroller":3.4203681286504293,"layer":3.70805020110221,"node":3.70805020110221,"npm":3.70805020110221,"creating":3.70805020110221,"bundling":3.70805020110221,"prepare":3.4203681286504293,"register":3.70805020110221,"change":3.70805020110221,"3000":3.70805020110221,"navigate":3.70805020110221,"home":3.70805020110221,"terminal":3.4203681286504293,"watch":3.4203681286504293,"another":3.70805020110221,"changes":3.1972245773362196,"instant":3.70805020110221,"rebuild":3.70805020110221,"specifying":3.70805020110221,"view_name":3.70805020110221,"tsx":3.70805020110221,"backend":3.70805020110221,"endpoint":3.1972245773362196,"shown":3.70805020110221,"below":3.70805020110221,"user_controller":3.70805020110221,"usercontroller":3.70805020110221,"fetch":3.70805020110221,"component":3.70805020110221,"import":3.70805020110221,"usestate":3.70805020110221,"useeffect":3.70805020110221,"functe":3.70805020110221,"const":3.4203681286504293,"setuser":3.70805020110221,"return":3.70805020110221,"map":3.70805020110221,"including":3.70805020110221,"hookable":4.113515309210374,"executes":4.113515309210374,"call":3.4203681286504293,"lambda":4.113515309210374,"index2":4.113515309210374,"unles":3.0149030205422647,"guard":3.70805020110221,"accept":4.113515309210374,"log":4.113515309210374,"print_hello":4.113515309210374,"hello":3.70805020110221,"res":4.113515309210374,"yield":4.113515309210374,"execute":3.70805020110221,"127":3.70805020110221,"feb":4.113515309210374,"2025":3.70805020110221,"0500":4.113515309210374,"401":4.113515309210374,"0359":4.113515309210374,"pinn":4.113515309210374,"anyclas":4.113515309210374,"print_world":4.113515309210374,"world":4.113515309210374,"class_method":4.113515309210374,"self":4.113515309210374,"validate":4.113515309210374,"validatable":4.113515309210374,"foo":4.113515309210374,"age":4.113515309210374,"condite":4.113515309210374,"length":4.113515309210374,"error_message":4.113515309210374,"message":3.4203681286504293,"must":4.113515309210374,"fancy_error":4.113515309210374,"fancy":4.113515309210374,"least":4.113515309210374,"year":4.113515309210374,"old":4.113515309210374,"041":4.113515309210374,"valid":4.113515309210374,"042":4.113515309210374,"046":4.113515309210374,"joe":4.113515309210374,"wrong":3.4203681286504293,"047":4.113515309210374,"format":4.113515309210374,"077":4.113515309210374,"078":4.113515309210374,"080":4.113515309210374,"validate_before_persist":4.113515309210374,"validate_after_setter":4.113515309210374,"setter":4.113515309210374,"global":3.70805020110221,"initializer":4.113515309210374,"such":4.113515309210374,"sequel_object_preloader":4.113515309210374,"preloader":4.113515309210374,"useful":4.113515309210374,"classes":4.113515309210374,"rubee_support":4.113515309210374,"extension":3.4203681286504293,"tolerates":4.113515309210374,"symbol":4.113515309210374,"interchangeab":4.113515309210374,"deep":4.113515309210374,"digging":4.113515309210374,"two":4.113515309210374,"deep_dig":4.113515309210374,"dig":4.113515309210374,"enrich":4.113515309210374,"helper":4.113515309210374,"pluralize":4.113515309210374,"singularize":4.113515309210374,"camelize":4.113515309210374,"testme":4.113515309210374,"snakeize":4.113515309210374,"test_me":4.113515309210374,"singular":4.113515309210374,"plural":4.113515309210374,"authtokenable":3.70805020110221,"authenticate":3.70805020110221,"create_user":4.113515309210374,"creates":4.113515309210374,"seed":4.113515309210374,"credential":4.113515309210374,"customize":4.113515309210374,"userscontroller":3.70805020110221,"auth_method":4.113515309210374,"auth":3.4203681286504293,"unauthenticat":4.113515309210374,"action":4.113515309210374,"reject":4.113515309210374,"login":3.70805020110221,"edit":3.70805020110221,"initializes":4.113515309210374,"token_header":3.70805020110221,"token":3.70805020110221,"header":3.70805020110221,"redirect":3.70805020110221,"else":3.70805020110221,"render_view":3.70805020110221,"users_edit":3.70805020110221,"logout":3.70805020110221,"unauthenticate":3.70805020110221,"zeroed_token_header":3.70805020110221,"zero":3.70805020110221,"restrict":4.113515309210374,"jwt_key":4.113515309210374,"startup":4.113515309210374,"security":4.113515309210374,"sdjwer0wer23j":4.113515309210374,"instead":4.113515309210374,"argument":3.4203681286504293,"user_model":4.113515309210374,"digest_password":4.113515309210374,"digest":4.113515309210374,"oauth":4.113515309210374,"oauth2":4.113515309210374,"point":4.113515309210374,"redirect_uri":4.113515309210374,"uri":4.113515309210374,"mysite":4.113515309210374,"oauth_callback":4.113515309210374,"callback":4.113515309210374,"client_id":4.113515309210374,"google_client_id":4.113515309210374,"google":4.113515309210374,"client_secret":4.113515309210374,"secret":4.113515309210374,"google_client_secret":4.113515309210374,"section":4.113515309210374,"oauth_login":4.113515309210374,"auth_client":4.113515309210374,"auth_code":4.113515309210374,"authorize_url":4.113515309210374,"authorize":4.113515309210374,"scope":4.113515309210374,"profile":4.113515309210374,"openid":4.113515309210374,"get_token":4.113515309210374,"user_info":4.113515309210374,"info":3.70805020110221,"parse":4.113515309210374,"www":4.113515309210374,"googleapis":4.113515309210374,"userinfo":4.113515309210374,"alt":4.113515309210374,"body":4.113515309210374,"raise":4.113515309210374,"found":4.113515309210374,"something":3.4203681286504293,"went":4.113515309210374,"rescue":3.70805020110221,"fail":4.113515309210374,"standarderror":3.70805020110221,"private":4.113515309210374,"token_url":4.113515309210374,"mode":2.860752340715006,"restarting":4.113515309210374,"together":4.113515309210374,"stop":4.113515309210374,"restart":4.113515309210374,"shorthand":4.113515309210374,"alias":3.4203681286504293,"pick":4.113515309210374,"prefix":4.113515309210374,"variable":4.113515309210374,"testing":4.113515309210374,"auth_tokenable_test":4.113515309210374,"tokenable":4.113515309210374,"sidekiq":3.70805020110221,"async_adapter":3.70805020110221,"sidekiqasync":3.70805020110221,"redis":3.4203681286504293,"yml":3.70805020110221,"6379":3.4203681286504293,"concurrency":3.70805020110221,"queues":3.70805020110221,"high":3.70805020110221,"worker":3.4203681286504293,"test_async_runner":3.4203681286504293,"runner":3.4203681286504293,"require_relative":3.70805020110221,"require":3.70805020110221,"relative":3.70805020110221,"testasyncrunner":3.4203681286504293,"sidekiq_option":3.70805020110221,"queue":3.70805020110221,"perform":3.4203681286504293,"codebase":3.70805020110221,"perform_async":3.4203681286504293,"threadasync":3.70805020110221,"yet":3.70805020110221,"caute":3.70805020110221,"setting":4.113515309210374,"mylogger":4.113515309210374,"level":4.113515309210374,"target_method":4.113515309210374,"now":4.113515309210374,"warn":4.113515309210374,"warning":4.113515309210374,"class_name":4.113515309210374,"critical":4.113515309210374,"fire":4.113515309210374,"second":4.113515309210374,"debug":3.4203681286504293,"000655":4.113515309210374,"sudo":4.113515309210374,"apt":4.113515309210374,"linux":4.113515309210374,"brew":4.113515309210374,"macos":4.113515309210374,"redis_url":4.113515309210374,"6378":4.113515309210374,"entry":4.113515309210374,"website":4.113515309210374,"pub":4.113515309210374,"sub":4.113515309210374,"capable":4.113515309210374,"system":4.113515309210374,"expect":4.113515309210374,"unsubscribe":4.113515309210374,"channel":4.113515309210374,"subscriber":4.113515309210374,"sender_id":4.113515309210374,"sender":4.113515309210374,"unsub":4.113515309210374,"arg":4.113515309210374,"websocket_connection":4.113515309210374,"remove":4.113515309210374,"merge":4.113515309210374,"status":4.113515309210374,"unsubscrib":4.113515309210374,"publish":4.113515309210374,"sender_name":4.113515309210374,"stream":4.113515309210374,"chat":4.113515309210374,"see":4.113515309210374,"assistant":2.504077396776274,"ship":4.113515309210374,"answer":3.0149030205422647,"question":3.70805020110221,"local":3.70805020110221,"idf":3.70805020110221,"knowledge":3.1972245773362196,"through":4.113515309210374,"ollama":3.1972245773362196,"language":4.113515309210374,"richer":4.113515309210374,"conversational":3.70805020110221,"external":4.113515309210374,"connecte":4.113515309210374,"building":3.70805020110221,"readme":3.4203681286504293,"parses":3.70805020110221,"computes":3.70805020110221,"vector":3.70805020110221,"writes":3.70805020110221,"bee_knowledge":3.4203681286504293,"lib":3.70805020110221,"session":3.70805020110221,"ask":3.70805020110221,"domestic":3.70805020110221,"anything":3.70805020110221,"exit":3.4203681286504293,"leave":3.70805020110221,"retrain":3.70805020110221,"quit":3.70805020110221,"bye":3.70805020110221,"shot":3.1972245773362196,"queste":3.70805020110221,"work":3.4203681286504293,"llm":3.1972245773362196,"enable":3.70805020110221,"detail":3.70805020110221,"retrieves":3.70805020110221,"most":3.70805020110221,"relevant":3.70805020110221,"passes":3.70805020110221,"context":3.70805020110221,"qwen2":3.4203681286504293,"llama3":3.70805020110221,"specifi":3.70805020110221,"pull":3.70805020110221,"answering":3.70805020110221,"displaying":3.70805020110221,"live":3.70805020110221,"download":3.70805020110221,"progres":3.70805020110221,"bar":3.70805020110221,"ollama_url":3.70805020110221,"remote":3.70805020110221,"11434":3.70805020110221,"bee_debug":3.70805020110221,"tmp":3.70805020110221,"bee_ollama_debug":3.70805020110221,"txt":3.70805020110221,"suggestion":3.70805020110221,"suggest":3.70805020110221,"five":3.70805020110221,"topic":3.70805020110221,"along":3.70805020110221,"link":3.70805020110221,"reference":3.70805020110221,"contributing":3.70805020110221,"interest":3.70805020110221,"guide":3.70805020110221,"spot":3.70805020110221,"discus":3.70805020110221,"discussion":3.70805020110221},"sections":[{"label":"Production ready","body":"Take a look at the ru.Bee demo site with full documentation: https://rubee.dedyn.io/\nWant to explore how it was built? https://github.com/nucleom42/rubee-site","parent":null,"vector":{"producte":0.1777319427344501,"ready":0.20836189890891232,"take":0.2680762143183734,"look":0.2680762143183734,"demo":0.2416522088025919,"site":0.4833044176051838,"full":0.16318976311695063,"documentate":0.1964800730106302,"http":0.2921831693449947,"dedyn":0.20836189890891232,"want":0.1964800730106302,"explore":0.22290407852641178,"built":0.1964800730106302,"github":0.2680762143183734,"com":0.15697843527024535,"nucleom42":0.2680762143183734}},{"label":"Stress tested","body":"CODE>wrk -t4 -c100 -d30s https://rubee.dedyn.io/docs\nCODE>Running 30s test @ https://rubee.dedyn.io/docs\nCODE> 4 threads and 100 connections\nCODE> Thread Stats Avg Stdev Max +/- Stdev\nCODE> Latency 304.95ms 33.22ms 551.86ms 90.38%\nCODE> Req/Sec 82.25 42.37 280.00 69.86%\nCODE> 9721 requests in 30.02s, 4.11MB read\nCODE>Requests/sec: 323.78\nCODE>Transfer/sec: 140.07KB\n\nShort output explanation:\n • Requests/sec: ~324\n • Average latency: ~305 ms\n • Total requests handled: 9,721\n • Hardware: Raspberry Pi 5 (8 GB) — single board computer\n • Server: ru.Bee app hosted via Nginx + HTTPS\n\nThis demonstrates ru.Bee's efficient architecture and suitability for lightweight deployments — even on low-power hardware.","parent":null,"vector":{"stres":0.09634874141179164,"test":0.09244615718531421,"code":0.24096833822507394,"wrk":0.09634874141179164,"c100":0.09634874141179164,"d30":0.09634874141179164,"http":0.15751946158116784,"dedyn":0.1497738750831706,"doc":0.1926974828235833,"running":0.06387828563857496,"30":0.09634874141179164,"thread":0.1926974828235833,"100":0.09634874141179164,"connection":0.08011351352518331,"stat":0.09634874141179164,"avg":0.09634874141179164,"stdev":0.1926974828235833,"max":0.08685174190746338,"latency":0.1926974828235833,"304":0.09634874141179164,"95m":0.09634874141179164,"22m":0.09634874141179164,"551":0.09634874141179164,"86m":0.09634874141179164,"req":0.09634874141179164,"sec":0.3853949656471666,"280":0.09634874141179164,"9721":0.09634874141179164,"request":0.3474069676298535,"02":0.09634874141179164,"11mb":0.09634874141179164,"read":0.08011351352518331,"323":0.09634874141179164,"transfer":0.09634874141179164,"140":0.09634874141179164,"07kb":0.09634874141179164,"short":0.08685174190746338,"output":0.07061651402085503,"explanate":0.09634874141179164,"324":0.09634874141179164,"average":0.09634874141179164,"305":0.09634874141179164,"total":0.08011351352518331,"handl":0.09634874141179164,"721":0.09634874141179164,"hardware":0.1926974828235833,"raspberry":0.09634874141179164,"single":0.06387828563857496,"board":0.09634874141179164,"computer":0.09634874141179164,"server":0.04915471015064869,"app":0.04915471015064869,"host":0.08011351352518331,"nginx":0.09634874141179164,"demonstrates":0.09634874141179164,"efficient":0.08685174190746338,"architecture":0.09634874141179164,"suitability":0.09634874141179164,"lightweight":0.08685174190746338,"deployment":0.09634874141179164,"even":0.09634874141179164,"low":0.08011351352518331,"power":0.08685174190746338}},{"label":"Comparison","body":"Here is a short web frameworks comparison built with Ruby, so you can evaluate your choice with ru.Bee.\n\nDisclaimer:\nThe comparison is based on generic and subjective information available on the internet and is not a real benchmark. It is aimed at giving you a general idea of the differences between the frameworks and is not intended as a direct comparison.","parent":null,"vector":{"comparison":0.6254413034599989,"here":0.1409480442360176,"short":0.1409480442360176,"web":0.15636032586499973,"framework":0.2600257127895323,"built":0.11460057476578399,"ruby":0.09518339627287731,"evaluate":0.15636032586499973,"choice":0.15636032586499973,"disclaimer":0.15636032586499973,"bas":0.12153086574311091,"generic":0.15636032586499973,"subjective":0.15636032586499973,"informate":0.15636032586499973,"available":0.09918829313680183,"internet":0.1409480442360176,"not":0.19837658627360366,"real":0.15636032586499973,"benchmark":0.15636032586499973,"aim":0.15636032586499973,"giving":0.15636032586499973,"general":0.15636032586499973,"idea":0.13001285639476615,"differences":0.15636032586499973,"between":0.15636032586499973,"intend":0.15636032586499973,"direct":0.10874109723421059}},{"label":"Features","body":"Lightweight – A minimal footprint focused on serving Ruby applications efficiently.\n\nModular – A modular approach to application development. Build a modular monolith app with ease by attaching as many subprojects as you need.\n\nContract-driven – Define your API contracts in a simple, declarative way, then generate all the boilerplate you need.\n\nFast – Optimized for speed, providing quick responses.\n\nRack-powered – Built on Rack. The full Rack API is available for easy integration.\n\nDatabases – Supports SQLite3, PostgreSQL, MySQL, and more via the Sequel gem.\n\nViews – JSON, ERB, and plain HTML out of the box.\n\nReact Ready – React is supported as a first-class ru.Bee view engine.\n\nBundlable – Charge your ru.Bee app with any gem you need. Update effortlessly via Bundler.\n\nORM-agnostic – Models are native ORM objects, but you can use them as blueprints for any data source.\n\nAuthenticatable – Easily add JWT authentication to any controller action.\n\nHooks – Add logic before, after, or around any controller action.\n\nTestable – Run all or selected tests using fast, beloved Minitest.\n\nAsyncable – Plug in async adapters and use any popular background job engine.\n\nConsole – Start an interactive console and reload on the fly.\n\nBackground Jobs – Schedule and process background jobs using your preferred async stack.\n\nWebSocket – Serve and handle WebSocket connections.\n\nLogger – Use any logger you want.","parent":null,"vector":{"features":0.08221142787009311,"lightweight":0.07410792928472561,"minimal":0.08221142787009311,"footprint":0.08221142787009311,"focus":0.08221142787009311,"serving":0.08221142787009311,"ruby":0.05004570612032573,"applicate":0.06835840553895682,"efficient":0.07410792928472561,"modular":0.20507521661687048,"approach":0.08221142787009311,"applicat":0.06389872845146204,"development":0.044802176150797166,"build":0.06025490695358931,"monolith":0.08221142787009311,"app":0.08388441506991645,"ease":0.07410792928472561,"attaching":0.08221142787009311,"many":0.06025490695358931,"subproject":0.06835840553895682,"ne":0.17152229932362006,"contract":0.14821585856945121,"driven":0.08221142787009311,"define":0.06025490695358931,"api":0.12779745690292407,"simple":0.07410792928472561,"declarative":0.08221142787009311,"way":0.08221142787009311,"then":0.06025490695358931,"generate":0.041942207534958226,"all":0.08664215488680746,"boilerplate":0.08221142787009311,"fast":0.16442285574018622,"optimiz":0.08221142787009311,"spe":0.07410792928472561,"providing":0.08221142787009311,"quick":0.08221142787009311,"responses":0.07410792928472561,"rack":0.19169618535438607,"power":0.07410792928472561,"built":0.06025490695358931,"full":0.05004570612032573,"available":0.0521514083682218,"easy":0.08221142787009311,"integrate":0.08221142787009311,"databases":0.06389872845146204,"support":0.08960435230159433,"sqlite3":0.07410792928472561,"postgresql":0.07410792928472561,"mysql":0.08221142787009311,"more":0.06835840553895682,"sequel":0.05717409977454002,"gem":0.10901076641564106,"view":0.08960435230159433,"json":0.04640188462245302,"erb":0.05450538320782053,"plain":0.07410792928472561,"html":0.07410792928472561,"box":0.06835840553895682,"react":0.11434819954908004,"ready":0.06389872845146204,"first":0.05004570612032573,"clas":0.037217815496447135,"engine":0.12779745690292407,"bundlable":0.08221142787009311,"charge":0.08221142787009311,"any":0.2784113077347181,"update":0.05004570612032573,"effortles":0.08221142787009311,"bundler":0.07410792928472561,"orm":0.13671681107791364,"agnostic":0.08221142787009311,"model":0.036192683789189425,"native":0.08221142787009311,"object":0.04814086673520795,"but":0.08221142787009311,"them":0.08221142787009311,"blueprint":0.08221142787009311,"data":0.05450538320782053,"source":0.08221142787009311,"authenticatable":0.08221142787009311,"easi":0.08221142787009311,"add":0.08664215488680746,"jwt":0.06389872845146204,"authenticat":0.06025490695358931,"controller":0.08960435230159433,"acte":0.11434819954908004,"hook":0.05717409977454002,"logic":0.06025490695358931,"before":0.05004570612032573,"after":0.05450538320782053,"around":0.07410792928472561,"testable":0.08221142787009311,"select":0.08221142787009311,"test":0.039440736183698644,"belov":0.08221142787009311,"minitest":0.08221142787009311,"asyncable":0.06389872845146204,"plug":0.07410792928472561,"async":0.12779745690292407,"adapter":0.06389872845146204,"popular":0.08221142787009311,"background":0.19169618535438607,"job":0.19169618535438607,"console":0.14821585856945121,"start":0.039440736183698644,"interactive":0.05717409977454002,"reload":0.06389872845146204,"f":0.08221142787009311,"schedule":0.08221142787009311,"proces":0.06835840553895682,"preferr":0.08221142787009311,"stack":0.07410792928472561,"websocket":0.12779745690292407,"serve":0.08221142787009311,"handle":0.08221142787009311,"connection":0.06835840553895682,"logger":0.14821585856945121,"want":0.06025490695358931}},{"label":"Installation","body":"1. Install ru.Bee\n\nCODE>gem install ru.Bee\n\n2. Create your first project\n\nCODE>rubee project my_project\nCODE>\nCODE>cd my_project\n\n3. Install dependencies\n\nPrerequisites: make sure Ruby (3.1 or higher, 3.4.1 recommended) and Bundler are installed.\n\nCODE>bundle install\n\n4. Run the ru.Bee server. Default port is 7000.\n\nCODE>rubee start # or rubee start_dev for development\nCODE>\nCODE># Starting from version 1.8.0, you can also start the server with the yjit compiler for a speed boost.\nCODE>rubee start --jit=yjit\nCODE># This option is available for the dev environment too.\nCODE>rubee start_dev --jit=yjit\n\n5. Open your browser and go to http://localhost:7000","parent":null,"vector":{"installate":0.11337110409130279,"install":0.3450698464242457,"code":0.34655046715197857,"gem":0.07516394780242086,"create":0.057839092440754934,"first":0.06901396928484914,"project":0.35247018971716043,"my_project":0.22674220818260557,"dependency":0.07884415810303534,"prerequisites":0.09426752594686183,"ruby":0.06901396928484914,"higher":0.11337110409130279,"recommend":0.09426752594686183,"bundler":0.10219622724720859,"bundle":0.09426752594686183,"server":0.11567818488150987,"default":0.05974057995859439,"port":0.09426752594686183,"7000":0.18853505189372366,"start":0.2719475821770961,"start_dev":0.15768831620607068,"dev":0.23653247430910607,"development":0.06178304291144233,"starting":0.08309264910276762,"version":0.07884415810303534,"yjit":0.3401133122739084,"compiler":0.11337110409130279,"spe":0.10219622724720859,"boost":0.11337110409130279,"jit":0.22674220818260557,"opte":0.11337110409130279,"available":0.07191777225867342,"environment":0.07191777225867342,"too":0.11337110409130279,"open":0.08309264910276762,"browser":0.09426752594686183,"http":0.06178304291144233,"localhost":0.07516394780242086}},{"label":"Run tests","body":"CODE>rubee test\nCODE># or specify a specific test file\nCODE>rubee test models/user_model_test.rb\nCODE># or run a specific line in the test file\nCODE>rubee test models/user_model_test.rb --line=12","parent":null,"vector":{"test":0.7007758001391987,"code":0.2536983946615137,"specify":0.1825897052159431,"specific":0.2138395328666772,"file":0.20611505368975666,"model":0.3215324990819652,"user_model_test":0.3291840395630555,"user":0.17519395003479968,"line":0.2838352354142814}},{"label":"Draw contract","body":"1. Add the routes to routes.rb\n\nCODE> Rubee::Router.draw do |router|\nCODE> ...\nCODE> # draw the contract\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE> end\nCODE>\n\n2. Generate the files\n\nCODE>rubee generate get /apples\n\nThis will generate the following files:\n\nCODE>./app/controllers/apples_controller.rb # Controller with respective action\nCODE>./app/views/apples_index.erb # ERB view rendered by the controller\nCODE>./app/models/apple.rb # Model that acts as ORM\nCODE>./db/create_apples.rb # Database migration file for the respective table\n\n3. Run the initial database migration\n\nCODE>rubee db run:all\n\n4. Fill the generated files with the logic you need and run the server again.\n\n5. You can find a full snapshot of the schema in the STRUCTURE constant or in the db/structure.rb file.\n\n6. Print the latest schema from the STRUCTURE constant via the CLI\n\nCODE>-> rubee db schema\nCODE>--- users\nCODE>- id, (PK), type (INTEGER)\nCODE>- email, type (varchar(255))\nCODE>- password, type (varchar(255))\nCODE>\nCODE>--- accounts\nCODE>- id, (PK), type (INTEGER)\nCODE>- address, type (varchar(255))\nCODE>- user_id, type (INTEGER)\nCODE>\nCODE>--- posts\nCODE>- id, (PK), type (INTEGER)\nCODE>- user_id, type (INTEGER)\nCODE>- comment_id, type (INTEGER)\nCODE>\nCODE>--- comments\nCODE>- id, (PK), type (INTEGER)\nCODE>- text, type (varchar(255))\nCODE>- user_id, type (INTEGER)\n\n7. Print the schema for a specific table\n\nCODE>-> rubee db schema posts\nCODE>--- posts\nCODE>- id, (PK), type (INTEGER)\nCODE>- user_id, type (INTEGER), nullable\nCODE>- comment_id, type (INTEGER), nullable\nCODE>- created, type (datetime), nullable\nCODE>- updated, type (datetime), nullable\nCODE>\nCODE> Foreign keys:\nCODE> - comment_id → comments() on delete no_action on update no_action\nCODE> - user_id → users() on delete no_action on update no_action\n\n8. Dropping all tables can be handy during development. Be careful and make sure you pass the desired environment.\n\nCODE>RACK_ENV=test rubee db drop_tables\nCODE>These tables have been dropped for the test env:\nCODE>[:companies, :company_clients, :services]","parent":null,"vector":{"draw":0.06936202920086003,"contract":0.06570965215702732,"add":0.019205859328067995,"routes":0.04268530558389672,"code":0.5671868321048535,"router":0.06656141872116525,"apples":0.13872405840172006,"index":0.04268530558389672,"model":0.04813672474803095,"name":0.1234301805785448,"apple":0.05342652284160446,"attributes":0.024164281783606346,"type":0.4225289052174959,"primary":0.02671326142080223,"colour":0.02671326142080223,"string":0.024164281783606346,"weight":0.02671326142080223,"integer":0.3205591370496268,"creat":0.05069484797155885,"datetime":0.10685304568320891,"updat":0.04832856356721269,"end":0.016045574916010313,"generate":0.05578366365961861,"files":0.0801397842624067,"app":0.05578366365961861,"controller":0.07944994386325464,"apples_controller":0.030305846441317782,"respective":0.07289482219805841,"acte":0.1267371199288971,"view":0.03972497193162732,"apples_index":0.030305846441317782,"erb":0.04832856356721269,"render":0.025347423985779424,"act":0.03644741109902921,"orm":0.030305846441317782,"create_apples":0.028328704231433185,"create":0.0185945545532062,"database":0.03972497193162732,"migrate":0.04832856356721269,"file":0.04114339352618159,"table":0.06570965215702732,"initial":0.030305846441317782,"all":0.03841171865613599,"fill":0.030305846441317782,"generat":0.02671326142080223,"logic":0.02671326142080223,"ne":0.025347423985779424,"server":0.0185945545532062,"again":0.03644741109902921,"find":0.028328704231433185,"full":0.02218713957372175,"snapshot":0.03644741109902921,"schema":0.1515292322065889,"structure":0.08498611269429956,"constant":0.07289482219805841,"print":0.06570965215702732,"latest":0.03285482607851366,"cli":0.030305846441317782,"user":0.12239890901846161,"email":0.020571696763090796,"varchar":0.14578964439611683,"255":0.14578964439611683,"password":0.02134265279194836,"account":0.03285482607851366,"addres":0.03644741109902921,"user_id":0.1515292322065889,"post":0.07249284535081904,"comment_id":0.09091753932395336,"comment":0.1515292322065889,"text":0.02671326142080223,"specific":0.02134265279194836,"nullable":0.14578964439611683,"foreign":0.030305846441317782,"key":0.024164281783606346,"delete":0.060611692882635564,"no_acte":0.14578964439611683,"update":0.0443742791474435,"dropping":0.03644741109902921,"tables":0.10934223329708764,"handy":0.03644741109902921,"during":0.03644741109902921,"development":0.01986248596581366,"careful":0.03644741109902921,"pas":0.028328704231433185,"desir":0.030305846441317782,"environment":0.023120676400286675,"rack_env":0.030305846441317782,"rack":0.028328704231433185,"env":0.04114339352618159,"test":0.034971116862417606,"drop_tables":0.03644741109902921,"drop":0.03644741109902921,"dropp":0.03644741109902921,"company":0.07289482219805841,"company_client":0.03644741109902921,"client":0.028328704231433185,"services":0.03644741109902921}},{"label":"Model","body":"A model in ru.Bee is a simple Ruby object that can be serialized in the view in whatever form is required (e.g. JSON).\nHere is a simple example of rendering JSON from an in-memory object:\n\nCODE># ApplesController\nCODE>\nCODE>def show\nCODE> # In-memory example\nCODE> apples = [Apple.new(colour: 'red', weight: '1lb'), Apple.new(colour: 'green', weight: '1lb')]\nCODE> apple = apples.find { |apple| apple.colour = params[:colour] }\nCODE>\nCODE> response_with object: apple, type: :json\nCODE>end\n\nMake sure the Serializable module is included in the target class:\n\nCODE>class Apple\nCODE> include Serializable\nCODE> attr_accessor :id, :colour, :weight\nCODE>end\n\nYou can also turn it into an ORM object by extending Rubee::SequelObject, which is already serializable and charged with hooks:\n\nCODE>class Apple user = User.new(email: \"llo@ok.com\", password: 543)\nCODE>=> #\n\nSave a record to the database\n\nCODE>irb(main):018> user.save\nCODE>=> true\n\nUpdate a record with a new value\n\nCODE>irb(main):019> user.update(email: \"update@email.com\")\nCODE>=> #\n\nCheck whether a record has been persisted\n\nCODE>irb(main):016> user.persisted?\nCODE>=> false\n\nGet a record from the database and reload it\n\nCODE>irb(main):011> user = User.last\nCODE>=> #\nCODE>irb(main):012> user.email = \"new@ok.com\"\nCODE>=> \"new@ok.com\"\nCODE>irb(main):014> user.reload\nCODE>=> # # unpersisted data refreshed from db\n\nAssign attributes without persisting to the database\n\nCODE>irb(main):008> User.last.assign_attributes(email: \"bb@ok.com\")\nCODE>=> {\"id\" => 2, \"email\" => \"ok23@ok.com\", \"password\" => \"123\"}\n\nGet all records scoped by a field\n\nCODE>irb(main):005> User.where(email: \"ok23@ok.com\")\nCODE>=> [#]\n\nGet all records\n\nCODE>irb(main):001> User.all\nCODE>=> [#]\n\nFind by id\n\nCODE>irb(main):002> user = User.find 1\nCODE>=> #\n\nGet the last record\n\nCODE>irb(main):003> User.last\nCODE>=> #\n\nCreate a new persisted record\n\nCODE>irb(main):004> User.create(email: \"ok23@ok.com\", password: 123)\nCODE>=> #\n\nDestroy a record and all related records\n\nCODE>irb(main):021> user.destroy(cascade: true)\nCODE>=> 1\n\nFind a record in the database or initialize a new instance for subsequent persistence\n\nCODE>irb(main):020> user = User.find_or_new(email: \"ok23@ok.com\")\nCODE>=> #\nCODE>irb(main):021> user.persisted?\nCODE>=> true\nCODE>irb(main):022> user = User.find_or_new(email: \"new@ok.com\")\nCODE>=> #\nCODE>irb(main):023> user.persisted?\nCODE>=> false\n\nDestroy all records one by one\n\nCODE>irb(main):022> User.destroy_all\nCODE>=> [#, #]\nCODE>irb(main):023> User.all\nCODE>=> []\n\nUse complex query chains and serialize results back to ru.Bee objects in a single query:\n\nCODE># user model\nCODE>class User result = Comment.dataset.join(:posts, comment_id: :id)\nCODE>irb(main):009> .where(comment_id: Comment.where(text: \"test\").last.id)\nCODE>irb(main):010> .then { |dataset| Comment.serialize(dataset) }\nCODE>=> [#]\n\nSince version 2.6.0, Rubee::SequelObject supports chained queries. Supported methods: where, order, limit, offset, all, owns_many, owns_one, join, paginate.\n\nCODE>irb(main):001> Comment.where(text: \"test\").where(user_id: 1)\nCODE>=> [#]\n\nA paginate method is also available:\n\nCODE>irb(main):001> comments = Comment.all.paginate(page: 1, per_page: 3)\nCODE>\nCODE>irb(main):001> comments.pagination_meta\nCODE>=> {:current_page=>1, :per_page=>3, :total_count=>10, :first_page=>true, :last_page=>false, :prev=>nil, :next=>2}","parent":null,"vector":{"model":0.030716953419891217,"simple":0.04193057037241045,"ruby":0.014158032902612763,"object":0.06809574966917603,"serializ":0.023257781555865043,"view":0.012674627520022502,"whatever":0.023257781555865043,"form":0.023257781555865043,"requir":0.016174670087359216,"json":0.039381564982721544,"here":0.020965285186205225,"rendering":0.023257781555865043,"memory":0.04193057037241045,"code":0.41363729414700723,"applescontroller":0.020965285186205225,"def":0.012674627520022502,"apples":0.029507480774459423,"apple":0.13636989405511626,"new":0.14981064927218726,"colour":0.08523118378444768,"r":0.023257781555865043,"weight":0.0511387102706686,"1lb":0.046515563111730086,"green":0.023257781555865043,"find":0.1084624879915707,"param":0.01933873312654936,"response_with":0.014753740387229711,"response":0.013619149933835204,"type":0.012255621658043527,"end":0.02047796894659415,"serializable":0.06977334466759515,"module":0.018077081331928452,"includ":0.023257781555865043,"target":0.020965285186205225,"clas":0.04211598534309102,"include":0.012255621658043527,"attr_accessor":0.020965285186205225,"attr":0.020965285186205225,"accessor":0.020965285186205225,"turn":0.023257781555865043,"orm":0.01933873312654936,"extending":0.023257781555865043,"sequelobject":0.03867746625309872,"already":0.023257781555865043,"charg":0.01933873312654936,"hook":0.016174670087359216,"user":0.3124202244041859,"email":0.1312718832757385,"llo":0.020965285186205225,"com":0.13619149933835206,"password":0.040857449801505616,"543":0.020965285186205225,"save":0.03867746625309872,"record":0.2515834222344627,"database":0.050698510080090006,"irb":0.46412959503718465,"main":0.3700724327336081,"018":0.020965285186205225,"true":0.05663213161045105,"update":0.04247409870783829,"value":0.01933873312654936,"019":0.020965285186205225,"check":0.020965285186205225,"whether":0.020965285186205225,"persist":0.09669366563274681,"016":0.020965285186205225,"false":0.0511387102706686,"reload":0.036154162663856904,"011":0.020965285186205225,"last":0.1084624879915707,"012":0.020965285186205225,"014":0.020965285186205225,"unpersist":0.020965285186205225,"data":0.015419684697233671,"refresh":0.020965285186205225,"assign":0.04193057037241045,"attributes":0.030839369394467343,"without":0.018077081331928452,"persisting":0.020965285186205225,"008":0.020965285186205225,"assign_attributes":0.020965285186205225,"ok23":0.0838611407448209,"123":0.030839369394467343,"all":0.11030059492239173,"scop":0.020965285186205225,"field":0.01933873312654936,"005":0.020965285186205225,"001":0.0838611407448209,"002":0.020965285186205225,"003":0.020965285186205225,"create":0.02373107306590588,"004":0.020965285186205225,"destroy":0.0838611407448209,"relat":0.018077081331928452,"021":0.04193057037241045,"cascade":0.020965285186205225,"initialize":0.018077081331928452,"instance":0.020965285186205225,"subsequent":0.020965285186205225,"persistence":0.01933873312654936,"020":0.020965285186205225,"find_or_new":0.04193057037241045,"022":0.04193057037241045,"023":0.04193057037241045,"one":0.040857449801505616,"destroy_all":0.020965285186205225,"complex":0.020965285186205225,"query":0.06289585555861567,"chain":0.04193057037241045,"serialize":0.04193057037241045,"result":0.04193057037241045,"back":0.020965285186205225,"single":0.015419684697233671,"comment":0.17404859813894424,"dataset":0.05801619937964808,"join":0.04193057037241045,"post":0.015419684697233671,"comment_id":0.03867746625309872,"009":0.020965285186205225,"text":0.034092473513779066,"test":0.022315730314584704,"010":0.020965285186205225,"then":0.017046236756889533,"since":0.020965285186205225,"version":0.016174670087359216,"support":0.025349255040045003,"method":0.028316065805225527,"order":0.020965285186205225,"limit":0.020965285186205225,"offset":0.020965285186205225,"owns_many":0.020965285186205225,"own":0.034092473513779066,"many":0.017046236756889533,"owns_one":0.020965285186205225,"paginate":0.0838611407448209,"user_id":0.01933873312654936,"available":0.014753740387229711,"page":0.12579171111723134,"per_page":0.04193057037241045,"per":0.04193057037241045,"pagination_meta":0.020965285186205225,"meta":0.020965285186205225,"current_page":0.020965285186205225,"current":0.020965285186205225,"total_count":0.020965285186205225,"total":0.01933873312654936,"count":0.020965285186205225,"first_page":0.020965285186205225,"first":0.014158032902612763,"last_page":0.020965285186205225,"prev":0.020965285186205225,"nil":0.020965285186205225,"next":0.018077081331928452}},{"label":"Model — Rubee::SequelObject base methods","body":"Initiate a new record in memory\n\nCODE>irb(main):015> user = User.new(email: \"llo@ok.com\", password: 543)\nCODE>=> #\n\nSave a record to the database\n\nCODE>irb(main):018> user.save\nCODE>=> true\n\nUpdate a record with a new value\n\nCODE>irb(main):019> user.update(email: \"update@email.com\")\nCODE>=> #\n\nCheck whether a record has been persisted\n\nCODE>irb(main):016> user.persisted?\nCODE>=> false\n\nGet a record from the database and reload it\n\nCODE>irb(main):011> user = User.last\nCODE>=> #\nCODE>irb(main):012> user.email = \"new@ok.com\"\nCODE>=> \"new@ok.com\"\nCODE>irb(main):014> user.reload\nCODE>=> # # unpersisted data refreshed from db\n\nAssign attributes without persisting to the database\n\nCODE>irb(main):008> User.last.assign_attributes(email: \"bb@ok.com\")\nCODE>=> {\"id\" => 2, \"email\" => \"ok23@ok.com\", \"password\" => \"123\"}\n\nGet all records scoped by a field\n\nCODE>irb(main):005> User.where(email: \"ok23@ok.com\")\nCODE>=> [#]\n\nGet all records\n\nCODE>irb(main):001> User.all\nCODE>=> [#]\n\nFind by id\n\nCODE>irb(main):002> user = User.find 1\nCODE>=> #\n\nGet the last record\n\nCODE>irb(main):003> User.last\nCODE>=> #\n\nCreate a new persisted record\n\nCODE>irb(main):004> User.create(email: \"ok23@ok.com\", password: 123)\nCODE>=> #\n\nDestroy a record and all related records\n\nCODE>irb(main):021> user.destroy(cascade: true)\nCODE>=> 1\n\nFind a record in the database or initialize a new instance for subsequent persistence\n\nCODE>irb(main):020> user = User.find_or_new(email: \"ok23@ok.com\")\nCODE>=> #\nCODE>irb(main):021> user.persisted?\nCODE>=> true\nCODE>irb(main):022> user = User.find_or_new(email: \"new@ok.com\")\nCODE>=> #\nCODE>irb(main):023> user.persisted?\nCODE>=> false\n\nDestroy all records one by one\n\nCODE>irb(main):022> User.destroy_all\nCODE>=> [#, #]\nCODE>irb(main):023> User.all\nCODE>=> []\n\nUse complex query chains and serialize results back to ru.Bee objects in a single query:\n\nCODE># user model\nCODE>class User result = Comment.dataset.join(:posts, comment_id: :id)\nCODE>irb(main):009> .where(comment_id: Comment.where(text: \"test\").last.id)\nCODE>irb(main):010> .then { |dataset| Comment.serialize(dataset) }\nCODE>=> [#]\n\nSince version 2.6.0, Rubee::SequelObject supports chained queries. Supported methods: where, order, limit, offset, all, owns_many, owns_one, join, paginate.\n\nCODE>irb(main):001> Comment.where(text: \"test\").where(user_id: 1)\nCODE>=> [#]\n\nA paginate method is also available:\n\nCODE>irb(main):001> comments = Comment.all.paginate(page: 1, per_page: 3)\nCODE>\nCODE>irb(main):001> comments.pagination_meta\nCODE>=> {:current_page=>1, :per_page=>3, :total_count=>10, :first_page=>true, :last_page=>false, :prev=>nil, :next=>2}","parent":"Model","vector":{"model":0.021420388325208636,"sequelobject":0.04045744715880717,"base":0.012411601994594967,"method":0.04442880494925531,"initiate":0.02432813106655103,"new":0.14245918674982128,"record":0.285091708348125,"memory":0.021930131411394233,"code":0.34478657738055085,"irb":0.5057180894850896,"main":0.4032329023064033,"015":0.02432813106655103,"user":0.326798157807516,"email":0.13731316437099333,"llo":0.021930131411394233,"com":0.14245918674982128,"password":0.04273775602494638,"543":0.021930131411394233,"save":0.04045744715880717,"database":0.053031713069652375,"018":0.021930131411394233,"true":0.059238406599007074,"update":0.04442880494925531,"value":0.020228723579403585,"019":0.021930131411394233,"check":0.021930131411394233,"whether":0.021930131411394233,"persist":0.10114361789701794,"016":0.021930131411394233,"false":0.05349217177274034,"reload":0.03781801827379844,"011":0.021930131411394233,"last":0.11345405482139531,"012":0.021930131411394233,"014":0.021930131411394233,"unpersist":0.021930131411394233,"data":0.016129316092256138,"refresh":0.021930131411394233,"assign":0.043860262822788466,"attributes":0.032258632184512276,"without":0.01890900913689922,"persisting":0.021930131411394233,"008":0.021930131411394233,"assign_attributes":0.021930131411394233,"ok23":0.08772052564557693,"123":0.032258632184512276,"all":0.11537675351989062,"scop":0.021930131411394233,"field":0.020228723579403585,"005":0.021930131411394233,"001":0.08772052564557693,"find":0.09454504568449609,"002":0.021930131411394233,"003":0.021930131411394233,"create":0.024823203989189933,"004":0.021930131411394233,"destroy":0.08772052564557693,"relat":0.01890900913689922,"021":0.043860262822788466,"cascade":0.021930131411394233,"initialize":0.01890900913689922,"instance":0.021930131411394233,"subsequent":0.021930131411394233,"persistence":0.020228723579403585,"020":0.021930131411394233,"find_or_new":0.043860262822788466,"022":0.043860262822788466,"023":0.043860262822788466,"one":0.04273775602494638,"destroy_all":0.021930131411394233,"complex":0.021930131411394233,"query":0.06579039423418269,"chain":0.043860262822788466,"serialize":0.043860262822788466,"result":0.043860262822788466,"back":0.021930131411394233,"object":0.014245918674982127,"single":0.016129316092256138,"clas":0.011013552700228203,"comment":0.18205851221463226,"dataset":0.06068617073821076,"join":0.043860262822788466,"post":0.016129316092256138,"comment_id":0.04045744715880717,"009":0.021930131411394233,"text":0.03566144784849356,"test":0.023342725557679713,"010":0.021930131411394233,"then":0.01783072392424678,"since":0.021930131411394233,"version":0.016919046767135296,"support":0.026515856534826188,"order":0.021930131411394233,"limit":0.021930131411394233,"offset":0.021930131411394233,"owns_many":0.021930131411394233,"own":0.03566144784849356,"many":0.01783072392424678,"owns_one":0.021930131411394233,"paginate":0.08772052564557693,"user_id":0.020228723579403585,"available":0.01543272426908998,"page":0.13158078846836538,"per_page":0.043860262822788466,"per":0.043860262822788466,"pagination_meta":0.021930131411394233,"meta":0.021930131411394233,"current_page":0.021930131411394233,"current":0.021930131411394233,"total_count":0.021930131411394233,"total":0.020228723579403585,"count":0.021930131411394233,"first_page":0.021930131411394233,"first":0.014809601649751768,"last_page":0.021930131411394233,"prev":0.021930131411394233,"nil":0.021930131411394233,"next":0.01890900913689922}},{"label":"Database","body":"ru.Bee supports Postgres and SQLite databases fully and can potentially be used with any database supported by the Sequel gem.\n\nWhen using SQLite, include sqlite3 in your Gemfile:\n\nCODE>gem 'sqlite3'\n\nDefine your database URLs for each environment in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :test) do |config|\nCODE> config.database_url = { url: 'sqlite://db/test.db', env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :production) do |config|\nCODE> config.database_url = { url: 'sqlite://db/production.db', env: }\nCODE> ...\nCODE>end\n\nFor PostgreSQL, include the pg gem and configure the URLs:\n\nCODE>gem 'pg'\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"postgres://postgres@localhost:5432/development\", env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :test) do |config|\nCODE> config.database_url = { url: \"postgres://postgres@localhost:5432/test\", env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :production) do |config|\nCODE> config.database_url = { url: \"postgres://postgres:#{ENV['DB_PASSWORD']}@localhost:5432/production\", env: }\nCODE> ...\nCODE>end\n\nBefore starting the server or running the test suite, ensure your database is initialized:\n\nCODE>rubee db init # ensures your database is created for each environment\nCODE>RACK_ENV=test rubee db run:all # runs all migrations for the test environment\nCODE>RACK_ENV=development rubee db run:all # runs all migrations for the development environment\n\nSQLite production ready\n\nStarting from version 1.9.0, the main issue with SQLite — write database locking — is resolved.\nYou can tune the retry configuration parameters as needed:\n\n```ruby","parent":null,"vector":{"database":0.2811322962556406,"support":0.04685538270927343,"postgres":0.3009266259829157,"sqlite":0.1995114486097141,"databases":0.03341354855344365,"ful":0.04298951799755939,"potential":0.04298951799755939,"us":0.035745576756616416,"any":0.02426420153229433,"sequel":0.029897145140645037,"gem":0.11400654206269377,"include":0.04530640779940413,"sqlite3":0.07750416802836055,"gemfile":0.031508142773237297,"code":0.34644316777912415,"define":0.031508142773237297,"url":0.3524295581244695,"each":0.07149115351323283,"environment":0.10908283515943275,"config":0.32725601825843603,"base_configurate":0.027270708789858187,"base":0.021932173329121563,"configurate":0.2013883189282683,"setup":0.15104123919620127,"env":0.36396302298441496,"development":0.1405661481278203,"database_url":0.17938287084387022,"end":0.11355399642934624,"test":0.1443688301436296,"producte":0.14250817757836723,"postgresql":0.038752084014180274,"configure":0.027270708789858187,"localhost":0.08550490654702034,"5432":0.12896855399267818,"db_password":0.04298951799755939,"password":0.02517353986603354,"before":0.026169607312500676,"starting":0.06301628554647459,"server":0.021932173329121563,"running":0.028501635515673442,"suite":0.04298951799755939,"ensure":0.04298951799755939,"initializ":0.04298951799755939,"init":0.038752084014180274,"ensures":0.04298951799755939,"creat":0.029897145140645037,"rack_env":0.07149115351323283,"rack":0.0668270971068873,"all":0.09061281559880827,"run":0.08597903599511877,"migrate":0.057003271031346885,"ready":0.03341354855344365,"version":0.029897145140645037,"main":0.028501635515673442,"issue":0.03341354855344365,"write":0.031508142773237297,"locking":0.038752084014180274,"resolv":0.038752084014180274,"tune":0.038752084014180274,"retry":0.035745576756616416,"parameter":0.035745576756616416,"need":0.029897145140645037,"ruby":0.026169607312500676}},{"label":"Database — SQLite production ready","body":"Starting from version 1.9.0, the main issue with SQLite — write database locking — is resolved.\nYou can tune the retry configuration parameters as needed:\n\n```ruby","parent":"Database","vector":{"database":0.31988717977074754,"sqlite":0.3891680006343473,"producte":0.19458400031717366,"ready":0.22811820531301716,"starting":0.2151097771217251,"version":0.2041113077995378,"main":0.19458400031717366,"issue":0.22811820531301716,"write":0.2151097771217251,"locking":0.26456501150468187,"resolv":0.26456501150468187,"tune":0.26456501150468187,"retry":0.2440392347001304,"configurate":0.17186270193452488,"parameter":0.2440392347001304,"need":0.2041113077995378,"ruby":0.1786629709300604}},{"label":"configure database write retries","body":"config.db_max_retries = { env:, value: 3 } # set to 0 to disable, or increase if needed\nconfig.db_retry_delay = { env:, value: 0.1 }\nconfig.db_busy_timeout = { env:, value: 1000 } # busy timeout in milliseconds before raising an error\n\nCODE>\nCODE>For ru.Bee model create and update methods, retries are added automatically. To use retries with a Sequel dataset directly:\nCODE>\nruby\nRubee::DBTools.with_retry { User.dataset.insert(email: \"test@ok.com\", password: \"123\") }\n```","parent":null,"vector":{"configure":0.07619145018673022,"database":0.06545446957728948,"write":0.08803038854187323,"retry":0.5992159613820974,"config":0.21099655203386472,"db_max_retry":0.12010812569274702,"max":0.10826918733760402,"env":0.2033747692384273,"value":0.2996079806910487,"disable":0.12010812569274702,"increase":0.12010812569274702,"need":0.08352943307274946,"db_retry_delay":0.12010812569274702,"delay":0.12010812569274702,"db_busy_timeout":0.12010812569274702,"busy":0.24021625138549405,"timeout":0.24021625138549405,"1000":0.12010812569274702,"millisecond":0.12010812569274702,"before":0.07311509016216719,"raising":0.12010812569274702,"error":0.08352943307274946,"code":0.100130197279247,"model":0.05287629136643638,"create":0.06127615180702418,"update":0.07311509016216719,"method":0.07311509016216719,"add":0.06329063427701867,"automatical":0.09986932689701625,"sequel":0.08352943307274946,"dataset":0.1997386537940325,"direct":0.08352943307274946,"ruby":0.07311509016216719,"dbtool":0.12010812569274702,"with_retry":0.12010812569274702,"user":0.057621586459386066,"insert":0.12010812569274702,"email":0.06779158974614244,"test":0.057621586459386066,"com":0.07033218401128825,"password":0.07033218401128825,"123":0.07963052810128544}},{"label":"Routing","body":"ru.Bee uses explicit routes. In routes.rb you can define routes for any of the main HTTP methods.\nYou can also include matched parameters denoted by { } in the route path, e.g. /path/to/{a_key}/somewhere.\n\nRouting methods\n\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/posts', to: 'posts#index'\nCODE> router.post '/posts', to: 'posts#create'\nCODE> router.patch '/posts/{id}', to: 'posts#update'\nCODE> router.put '/posts/{id}', to: 'posts#update'\nCODE> router.delete '/posts/{id}', to: 'posts#delete'\nCODE> router.head '/posts', to: 'posts#index'\nCODE> router.connect '/posts', to: 'posts#index'\nCODE> router.options '/posts', to: 'posts#index'\nCODE> router.trace '/posts', to: 'posts#index'\nCODE>end\n\nEvery route follows this structure:\n\nCODE>route.{http_method} {path}, to: \"{controller}#{action}\",\nCODE> model: { ...optional }, namespace: { ...optional }, react: { ...optional }\n\nDefining model attributes in routes\n\nOne of ru.Bee's unique traits is defining models for generation directly in the routes:\n\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE>end\n\nOther supported attribute types via Sequel:\n\nCODE>[\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'description', type: :text },\nCODE> { name: 'quantity', type: :integer },\nCODE> { name: 'created', type: :date },\nCODE> { name: 'modified', type: :datetime },\nCODE> { name: 'exists', type: :time },\nCODE> { name: 'active', type: :boolean },\nCODE> { name: 'hash', type: :bigint },\nCODE> { name: 'price', type: :decimal },\nCODE> { name: 'item_id', type: :foreign_key },\nCODE> { name: 'item_id_index', type: :index },\nCODE> { name: 'item_id_unique', type: :unique }\nCODE>]\n\nEvery attribute can carry options based on the Sequel schema definition. For example:\n\nCODE>{ name: 'key', type: :string, options: { size: 50, fixed: true } }\n\nGets translated to:\n\nCODE>String :key, size: 50, fixed: true\n\nGeneration from routes\n\nAs long as a route has a model: key, you can use it to generate initial model files. If only path and to: are defined, only a controller and view will be generated.\n\nCODE>rubee generate get /apples # or: rubee gen get /apples\nCODE>rubee generate patch /apples/{id} # or: rubee gen patch /apples/{id}\n\nExample 1 — route without a model:\n\nCODE>router.get \"/apples\", to: \"apples#index\"\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\n\nExample 2 — route with a model name only:\n\nCODE>router.get \"/apples\", to: \"apples#index\", model: { name: 'apple' }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\nCODE>./app/models/apple.rb\nCODE>./db/create_apples.rb\n\nExample 3 — route with full model attributes:\n\nCODE>router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: 'apple',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/models/apple.rb\nCODE>./app/views/apples_index.erb\nCODE>./db/create_apples.rb\n\nModular application\n\nru.Bee supports modular applications — attach as many subprojects as you need. Each subproject gets its own folder, MVC setup, routes, and namespacing, while still sharing data with the main app.\n\n1. Attach a new subproject\n\nCODE>rubee attach admin\n\n2. Add routes\n\nCODE># admin_routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/admin/cabbages', to: 'cabbages#index',\nCODE> model: {\nCODE> name: 'cabbage',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> },\nCODE> namespace: :admin # mandatory for namespacing support\nCODE>end\n\n3. Run the generate command\n\nCODE>rubee gen get /admin/cabbages app:admin\n\nGenerates:\n\nCODE>./admin/controllers/cabbages_controller.rb\nCODE>./admin/views/cabbages_index.erb\nCODE>./admin/models/cabbage.rb\nCODE>./db/create_cabbages.rb\n\n4. Run the migration\n\nCODE>rubee db run:create_cabbages\n\n5. Fill the controller with content\n\nCODE># ./admin/controllers/cabbages_controller.rb\nCODE>class Admin::CabbagesController < Rubee::BaseController\nCODE> def index\nCODE> response_with object: Cabbage.all, type: :json\nCODE> end\nCODE>end\n\n6. Run the server\n\nCODE>rubee start # or rubee start_dev for development","parent":null,"vector":{"routing":0.028804651474450937,"uses":0.01965044547192626,"explicit":0.017713520628153744,"routes":0.10356109255536287,"define":0.014402325737225469,"any":0.011091130846297195,"main":0.026056111380139427,"http":0.021417526547915382,"method":0.03588626708109722,"include":0.01035474619698678,"match":0.017713520628153744,"parameter":0.01633925058099799,"denot":0.01965044547192626,"route":0.09566158761540537,"path":0.057609302948901875,"a_key":0.01965044547192626,"key":0.06514027845034856,"somewhere":0.01965044547192626,"code":0.5296824233079188,"router":0.2392417805406481,"draw":0.03739620268035885,"post":0.24753305811132453,"index":0.19561539704901876,"create":0.05012582091629944,"patch":0.04901775174299397,"update":0.023924178054064816,"put":0.01633925058099799,"delete":0.03267850116199598,"head":0.017713520628153744,"connect":0.017713520628153744,"option":0.03588626708109722,"trace":0.017713520628153744,"end":0.04325447068052066,"every":0.028804651474450937,"follow":0.017713520628153744,"structure":0.015273283917960684,"http_method":0.017713520628153744,"controller":0.13921392256145,"acte":0.013665941087915051,"model":0.12976341204156197,"optional":0.04581985175388205,"namespace":0.03267850116199598,"react":0.013665941087915051,"defining":0.03542704125630749,"attributes":0.06514027845034856,"one":0.011506788061706985,"unique":0.053140561884461236,"trait":0.017713520628153744,"generate":0.06015098509955933,"direct":0.013665941087915051,"apples":0.24930801786905898,"name":0.38818957962040185,"apple":0.07201162868612733,"type":0.30028763971261657,"primary":0.057609302948901875,"colour":0.028804651474450937,"string":0.07816833414041828,"weight":0.028804651474450937,"integer":0.043206977211676406,"creat":0.054663764351660205,"datetime":0.10081628016057827,"updat":0.03908416707020914,"other":0.017713520628153744,"support":0.03212628982187307,"attribute":0.03267850116199598,"types":0.017713520628153744,"sequel":0.027331882175830102,"descripte":0.017713520628153744,"text":0.014402325737225469,"quantity":0.017713520628153744,"date":0.017713520628153744,"modifi":0.017713520628153744,"exist":0.017713520628153744,"time":0.014402325737225469,"active":0.017713520628153744,"boolean":0.017713520628153744,"hash":0.01633925058099799,"bigint":0.017713520628153744,"price":0.017713520628153744,"decimal":0.017713520628153744,"item_id":0.017713520628153744,"item":0.053140561884461236,"foreign_key":0.017713520628153744,"foreign":0.01633925058099799,"item_id_index":0.017713520628153744,"item_id_unique":0.017713520628153744,"carry":0.017713520628153744,"bas":0.015273283917960684,"schema":0.01633925058099799,"definite":0.017713520628153744,"size":0.03542704125630749,"fix":0.03542704125630749,"true":0.023924178054064816,"get":0.03267850116199598,"translat":0.017713520628153744,"long":0.017713520628153744,"initial":0.01633925058099799,"files":0.014402325737225469,"on":0.04901775174299397,"defin":0.015273283917960684,"view":0.05354381636978845,"generat":0.014402325737225469,"gen":0.03908416707020914,"without":0.015273283917960684,"generates":0.06535700232399196,"app":0.10025164183259888,"apples_controller":0.04901775174299397,"apples_index":0.04901775174299397,"erb":0.052112222760278853,"create_apples":0.030546567835921367,"full":0.011962089027032408,"modular":0.03267850116199598,"applicat":0.015273283917960684,"applicate":0.01633925058099799,"attach":0.053140561884461236,"many":0.014402325737225469,"subproject":0.04901775174299397,"ne":0.013665941087915051,"each":0.01633925058099799,"own":0.014402325737225469,"folder":0.017713520628153744,"mvc":0.017713520628153744,"setup":0.011506788061706985,"namespacing":0.03542704125630749,"while":0.017713520628153744,"still":0.017713520628153744,"sharing":0.017713520628153744,"data":0.013028055690069713,"new":0.011506788061706985,"admin":0.19484872690969116,"add":0.01035474619698678,"admin_routes":0.017713520628153744,"cabbages":0.14170816502522995,"cabbage":0.053140561884461236,"mandatory":0.01633925058099799,"command":0.011506788061706985,"cabbages_controller":0.03542704125630749,"cabbages_index":0.017713520628153744,"create_cabbages":0.03542704125630749,"migrate":0.013028055690069713,"fill":0.01633925058099799,"content":0.017713520628153744,"clas":0.008895924483306488,"cabbagescontroller":0.017713520628153744,"basecontroller":0.014402325737225469,"def":0.010708763273957691,"response_with":0.012465400893452949,"response":0.011506788061706985,"object":0.011506788061706985,"all":0.01035474619698678,"json":0.011091130846297195,"server":0.010025164183259888,"start":0.01885450857209449,"start_dev":0.013665941087915051,"dev":0.013665941087915051,"development":0.010708763273957691}},{"label":"Routing — Routing methods","body":"CODE>Rubee::Router.draw do |router|\nCODE> router.get '/posts', to: 'posts#index'\nCODE> router.post '/posts', to: 'posts#create'\nCODE> router.patch '/posts/{id}', to: 'posts#update'\nCODE> router.put '/posts/{id}', to: 'posts#update'\nCODE> router.delete '/posts/{id}', to: 'posts#delete'\nCODE> router.head '/posts', to: 'posts#index'\nCODE> router.connect '/posts', to: 'posts#index'\nCODE> router.options '/posts', to: 'posts#index'\nCODE> router.trace '/posts', to: 'posts#index'\nCODE>end\n\nEvery route follows this structure:\n\nCODE>route.{http_method} {path}, to: \"{controller}#{action}\",\nCODE> model: { ...optional }, namespace: { ...optional }, react: { ...optional }","parent":"Routing","vector":{"routing":0.09248881918725296,"method":0.0768181132206608,"code":0.22793645512956126,"router":0.4224996227136344,"draw":0.040025140049127,"post":0.7948035849290719,"index":0.18473565656734697,"create":0.03218978706583092,"patch":0.05246367913812596,"update":0.0768181132206608,"put":0.05246367913812596,"delete":0.10492735827625192,"head":0.056876321103906564,"connect":0.056876321103906564,"option":0.0384090566103304,"trace":0.056876321103906564,"end":0.02777714510005032,"every":0.04624440959362648,"route":0.08775990609884088,"follow":0.056876321103906564,"structure":0.04904096812061048,"http_method":0.056876321103906564,"http":0.03438475452628428,"path":0.04624440959362648,"controller":0.03438475452628428,"acte":0.04387995304942044,"model":0.02777714510005032,"optional":0.14712290436183145,"namespace":0.05246367913812596,"react":0.04387995304942044}},{"label":"Routing — Defining model attributes in routes","body":"One of ru.Bee's unique traits is defining models for generation directly in the routes:\n\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE>end\n\nOther supported attribute types via Sequel:\n\nCODE>[\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'description', type: :text },\nCODE> { name: 'quantity', type: :integer },\nCODE> { name: 'created', type: :date },\nCODE> { name: 'modified', type: :datetime },\nCODE> { name: 'exists', type: :time },\nCODE> { name: 'active', type: :boolean },\nCODE> { name: 'hash', type: :bigint },\nCODE> { name: 'price', type: :decimal },\nCODE> { name: 'item_id', type: :foreign_key },\nCODE> { name: 'item_id_index', type: :index },\nCODE> { name: 'item_id_unique', type: :unique }\nCODE>]\n\nEvery attribute can carry options based on the Sequel schema definition. For example:\n\nCODE>{ name: 'key', type: :string, options: { size: 50, fixed: true } }\n\nGets translated to:\n\nCODE>String :key, size: 50, fixed: true","parent":"Routing","vector":{"routing":0.03629662559183412,"defining":0.08928294469712304,"model":0.0654057416604275,"attributes":0.06566640252411361,"routes":0.05799862961866666,"one":0.02899931480933333,"unique":0.13392441704568459,"trait":0.04464147234856152,"generate":0.02526533821658648,"direct":0.0344407949159239,"code":0.4266179690131633,"router":0.09044028193060971,"draw":0.031415203164884026,"apples":0.06283040632976805,"index":0.086997944428,"name":0.586987355537241,"apple":0.03629662559183412,"type":0.4958230150247336,"primary":0.07259325118366824,"colour":0.03629662559183412,"string":0.13133280504822722,"weight":0.03629662559183412,"integer":0.07259325118366824,"creat":0.0688815898318478,"datetime":0.10888987677550237,"updat":0.032833201262056806,"end":0.021801913886809163,"other":0.04464147234856152,"support":0.02698813915184406,"attribute":0.08235609603756842,"types":0.04464147234856152,"sequel":0.0688815898318478,"descripte":0.04464147234856152,"text":0.03629662559183412,"quantity":0.04464147234856152,"date":0.04464147234856152,"modifi":0.04464147234856152,"exist":0.04464147234856152,"time":0.03629662559183412,"active":0.04464147234856152,"boolean":0.04464147234856152,"hash":0.04117804801878421,"bigint":0.04464147234856152,"price":0.04464147234856152,"decimal":0.04464147234856152,"item_id":0.04464147234856152,"item":0.13392441704568459,"foreign_key":0.04464147234856152,"foreign":0.04117804801878421,"key":0.09849960378617043,"item_id_index":0.04464147234856152,"item_id_unique":0.04464147234856152,"every":0.03629662559183412,"carry":0.04464147234856152,"option":0.06029352128707314,"bas":0.03849160740026397,"schema":0.04117804801878421,"definite":0.04464147234856152,"size":0.08928294469712304,"fix":0.08928294469712304,"true":0.06029352128707314,"get":0.04117804801878421,"translat":0.04464147234856152}},{"label":"Routing — Generation from routes","body":"As long as a route has a model: key, you can use it to generate initial model files. If only path and to: are defined, only a controller and view will be generated.\n\nCODE>rubee generate get /apples # or: rubee gen get /apples\nCODE>rubee generate patch /apples/{id} # or: rubee gen patch /apples/{id}\n\nExample 1 — route without a model:\n\nCODE>router.get \"/apples\", to: \"apples#index\"\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\n\nExample 2 — route with a model name only:\n\nCODE>router.get \"/apples\", to: \"apples#index\", model: { name: 'apple' }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\nCODE>./app/models/apple.rb\nCODE>./db/create_apples.rb\n\nExample 3 — route with full model attributes:\n\nCODE>router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: 'apple',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/models/apple.rb\nCODE>./app/views/apples_index.erb\nCODE>./db/create_apples.rb","parent":"Routing","vector":{"routing":0.03951259023342376,"generate":0.11001562153870707,"routes":0.0315687209052577,"long":0.04859680963627276,"route":0.1499693147378905,"model":0.21360252312736164,"key":0.03574229852956496,"initial":0.04482651793241396,"files":0.03951259023342376,"on":0.13447955379724189,"path":0.03951259023342376,"defin":0.04190205248651597,"controller":0.20565545316051095,"view":0.11751740180600626,"generat":0.03951259023342376,"code":0.37453008374155883,"apples":0.615575925619804,"gen":0.07148459705912992,"patch":0.08965303586482792,"without":0.04190205248651597,"router":0.0984534992510009,"index":0.18941232543154615,"generates":0.13447955379724189,"app":0.22003124307741415,"apples_controller":0.13447955379724189,"apples_index":0.13447955379724189,"erb":0.10722689558869486,"name":0.24342696664459806,"apple":0.15805036093369504,"create_apples":0.08380410497303194,"create":0.055007810769353536,"full":0.03281783308366697,"attributes":0.07148459705912992,"type":0.1420405464081181,"primary":0.03951259023342376,"colour":0.03951259023342376,"string":0.03574229852956496,"weight":0.03951259023342376,"integer":0.03951259023342376,"creat":0.03749232868447262,"datetime":0.07902518046684752,"updat":0.03574229852956496}},{"label":"Routing — Modular application","body":"ru.Bee supports modular applications — attach as many subprojects as you need. Each subproject gets its own folder, MVC setup, routes, and namespacing, while still sharing data with the main app.\n\n1. Attach a new subproject\n\nCODE>rubee attach admin\n\n2. Add routes\n\nCODE># admin_routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/admin/cabbages', to: 'cabbages#index',\nCODE> model: {\nCODE> name: 'cabbage',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> },\nCODE> namespace: :admin # mandatory for namespacing support\nCODE>end\n\n3. Run the generate command\n\nCODE>rubee gen get /admin/cabbages app:admin\n\nGenerates:\n\nCODE>./admin/controllers/cabbages_controller.rb\nCODE>./admin/views/cabbages_index.erb\nCODE>./admin/models/cabbage.rb\nCODE>./db/create_cabbages.rb\n\n4. Run the migration\n\nCODE>rubee db run:create_cabbages\n\n5. Fill the controller with content\n\nCODE># ./admin/controllers/cabbages_controller.rb\nCODE>class Admin::CabbagesController < Rubee::BaseController\nCODE> def index\nCODE> response_with object: Cabbage.all, type: :json\nCODE> end\nCODE>end\n\n6. Run the server\n\nCODE>rubee start # or rubee start_dev for development","parent":"Routing","vector":{"routing":0.04133907337826684,"modular":0.09379727844481965,"applicat":0.04383898935015423,"support":0.061474842167805036,"applicate":0.046898639222409826,"attach":0.15252964189152346,"many":0.04133907337826684,"subproject":0.1406959176672295,"ne":0.03922542454071895,"each":0.046898639222409826,"get":0.046898639222409826,"own":0.04133907337826684,"folder":0.05084321396384116,"mvc":0.05084321396384116,"setup":0.033027995943848656,"routes":0.09908398783154597,"namespacing":0.10168642792768232,"while":0.05084321396384116,"still":0.05084321396384116,"sharing":0.05084321396384116,"data":0.037394498636835506,"main":0.037394498636835506,"app":0.057550565840873834,"new":0.033027995943848656,"code":0.43886401031718564,"admin":0.5592753536022527,"add":0.029721283955144638,"admin_routes":0.05084321396384116,"router":0.1030045462937397,"draw":0.03577950753412385,"cabbages":0.40674571171072926,"index":0.09908398783154597,"model":0.04966141635801116,"name":0.1910095967561551,"cabbage":0.15252964189152346,"attributes":0.037394498636835506,"type":0.14860641977572314,"primary":0.04133907337826684,"string":0.037394498636835506,"creat":0.03922542454071895,"datetime":0.08267814675653368,"updat":0.037394498636835506,"namespace":0.046898639222409826,"mandatory":0.046898639222409826,"end":0.07449212453701674,"generate":0.028775282920436917,"command":0.033027995943848656,"gen":0.037394498636835506,"generates":0.046898639222409826,"controller":0.15368710541951255,"cabbages_controller":0.10168642792768232,"view":0.030737421083902518,"cabbages_index":0.05084321396384116,"erb":0.037394498636835506,"create_cabbages":0.10168642792768232,"create":0.057550565840873834,"migrate":0.037394498636835506,"fill":0.046898639222409826,"content":0.05084321396384116,"clas":0.02553402010846148,"cabbagescontroller":0.05084321396384116,"basecontroller":0.04133907337826684,"def":0.030737421083902518,"response_with":0.03577950753412385,"response":0.033027995943848656,"object":0.033027995943848656,"all":0.029721283955144638,"json":0.03183493279269252,"server":0.028775282920436917,"start":0.054118197824008375,"start_dev":0.03922542454071895,"dev":0.03922542454071895,"development":0.030737421083902518}},{"label":"Views","body":"A view in ru.Bee is a plain HTML, ERB, or React file rendered from the controller.\n\nTemplates with ERB\n\nlayout.erb is the parent template rendered first; child templates are rendered inside it. Feel free to include custom CSS and JS files there.\n\nCODE># app/controllers/welcome_controller.rb\nCODE>\nCODE>class WelcomeController\nCODE>\nCODE>All set up and running!\n\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\n\nReact as a view\n\nReact is supported out of the box as a view layer in ru.Bee.\n\nPrerequisites: Node and NPM are required.\n\n1. After creating your project and bundling, install React dependencies:\n\nCODE>rubee react prepare\n\n2. Configure React in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE>\nCODE> # register React as a view\nCODE> config.react = { on: true, env: }\nCODE>end\n\n3. Start the server:\n\nCODE>rubee start\nCODE># Default port is 7000. To change it:\nCODE>rubee start --port=3000\n\n4. Open your browser and navigate to http://localhost:3000/home.\n\n5. For development, run rubee start_dev in one terminal and rubee react watch in another. Changes apply instantly.\n\n6. In production, rebuild the React app with rubee react build. Not needed in development when using rubee react watch.\n\n7. Generate a React view from a route by specifying the view name:\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get('/', to: 'welcome#show')\nCODE>\nCODE> router.get('/api/users', to: 'user#index', react: { view_name: 'users.tsx' })\nCODE> # Note: /api/users is the backend endpoint.\nCODE> # To render /app/views/users.tsx, update the React routes as shown below.\nCODE>end\n\n8. Add logic to the generated API controller:\n\nCODE># app/controllers/api/user_controller.rb\nCODE>class Api::UserController\nCODE>\nCODE> } />\nCODE> } />\nCODE>\nCODE>\n\n10. Fetch data from the backend in the component:\n\nCODE>// app/views/users.tsx\nCODE>import { useState, useEffect } from 'react';\nCODE>\nCODE>function Users() {\nCODE> const [users, setUsers] = useState([]);\nCODE>\nCODE> useEffect(() => {\nCODE> fetch('/api/users')\nCODE> .then(response => response.json())\nCODE> .then(data => setUsers(data));\nCODE> }, []);\nCODE>\nCODE> return (\nCODE>\nCODE> Users\nCODE>\nCODE> {users.map(user => (\nCODE> id: {user.id}: {user.name}\nCODE> ))}\nCODE>\nCODE>\nCODE> );\nCODE>}","parent":null,"vector":{"view":0.21229475240673804,"plain":0.03511598286191048,"html":0.03511598286191048,"erb":0.07748199636994252,"react":0.433470421253121,"file":0.021987495817107565,"render":0.10836760531328025,"controller":0.12737685144404284,"templates":0.07023196572382095,"layout":0.03511598286191048,"parent":0.03511598286191048,"template":0.03511598286191048,"first":0.023714117711770764,"child":0.03511598286191048,"inside":0.03239157564571563,"feel":0.03027836123417222,"free":0.03027836123417222,"include":0.020527657805918607,"custom":0.02855173933950902,"cs":0.03511598286191048,"files":0.02855173933950902,"there":0.03511598286191048,"code":0.6386983293118784,"app":0.11924568843338494,"welcome_controller":0.03239157564571563,"welcome":0.06055672246834444,"clas":0.035271264053531114,"welcomecontroller":0.03239157564571563,"all":0.020527657805918607,"running":0.025827332123314173,"support":0.021229475240673805,"box":0.03239157564571563,"layer":0.03511598286191048,"prerequisites":0.03239157564571563,"node":0.03511598286191048,"npm":0.03511598286191048,"requir":0.027091901328320064,"after":0.025827332123314173,"creating":0.03511598286191048,"project":0.03027836123417222,"bundling":0.03511598286191048,"install":0.023714117711770764,"dependency":0.027091901328320064,"prepare":0.03239157564571563,"configure":0.024711903033302413,"config":0.11405755548343935,"base_configurate":0.024711903033302413,"base":0.019874281405564156,"configurate":0.045623022193375745,"setup":0.022811511096687873,"env":0.0659624874513227,"development":0.08491790096269522,"database_url":0.027091901328320064,"database":0.021229475240673805,"url":0.045623022193375745,"sqlite":0.025827332123314173,"register":0.03511598286191048,"true":0.023714117711770764,"end":0.0342997483787386,"start":0.07475584484713738,"server":0.019874281405564156,"default":0.020527657805918607,"port":0.06478315129143127,"7000":0.03239157564571563,"change":0.03511598286191048,"3000":0.07023196572382095,"open":0.02855173933950902,"browser":0.03239157564571563,"navigate":0.03511598286191048,"http":0.021229475240673805,"localhost":0.025827332123314173,"home":0.03511598286191048,"start_dev":0.027091901328320064,"dev":0.027091901328320064,"one":0.022811511096687873,"terminal":0.03239157564571563,"watch":0.06478315129143127,"another":0.03511598286191048,"changes":0.03027836123417222,"instant":0.03511598286191048,"producte":0.025827332123314173,"rebuild":0.03511598286191048,"build":0.02855173933950902,"not":0.024711903033302413,"need":0.027091901328320064,"generate":0.019874281405564156,"route":0.027091901328320064,"specifying":0.03511598286191048,"name":0.0659624874513227,"routes":0.045623022193375745,"router":0.09485647084708305,"draw":0.024711903033302413,"api":0.18167016740503333,"user":0.28033441817676513,"index":0.022811511096687873,"view_name":0.03511598286191048,"tsx":0.10534794858573146,"backend":0.07023196572382095,"endpoint":0.03027836123417222,"update":0.023714117711770764,"shown":0.03511598286191048,"below":0.03511598286191048,"add":0.020527657805918607,"logic":0.02855173933950902,"generat":0.02855173933950902,"user_controller":0.03511598286191048,"usercontroller":0.03511598286191048,"fetch":0.07023196572382095,"data":0.07748199636994252,"component":0.03511598286191048,"import":0.03511598286191048,"usestate":0.07023196572382095,"useeffect":0.07023196572382095,"functe":0.03511598286191048,"const":0.03239157564571563,"setuser":0.07023196572382095,"then":0.05710347867901804,"response":0.045623022193375745,"json":0.021987495817107565,"return":0.03511598286191048,"map":0.03511598286191048}},{"label":"Views — Templates with ERB","body":"layout.erb is the parent template rendered first; child templates are rendered inside it. Feel free to include custom CSS and JS files there.\n\nCODE># app/controllers/welcome_controller.rb\nCODE>\nCODE>class WelcomeController\nCODE>\nCODE>All set up and running!\n\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>","parent":"Views","vector":{"view":0.10043970147490709,"templates":0.3322775335389116,"erb":0.24438564768562027,"layout":0.1661387667694558,"parent":0.1661387667694558,"template":0.1661387667694558,"render":0.25635136534988046,"first":0.11219490245089375,"child":0.1661387667694558,"inside":0.15324920429141461,"feel":0.14325128289949826,"free":0.14325128289949826,"include":0.09711930222633576,"custom":0.13508238632085132,"cs":0.1661387667694558,"files":0.13508238632085132,"there":0.1661387667694558,"code":0.563381533613132,"app":0.09402808448033047,"controller":0.20087940294981418,"welcome_controller":0.15324920429141461,"welcome":0.14325128289949826,"clas":0.08343671221302515,"welcomecontroller":0.15324920429141461,"all":0.09711930222633576,"running":0.12219282384281013}},{"label":"Views — React as a view","body":"React is supported out of the box as a view layer in ru.Bee.\n\nPrerequisites: Node and NPM are required.\n\n1. After creating your project and bundling, install React dependencies:\n\nCODE>rubee react prepare\n\n2. Configure React in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE>\nCODE> # register React as a view\nCODE> config.react = { on: true, env: }\nCODE>end\n\n3. Start the server:\n\nCODE>rubee start\nCODE># Default port is 7000. To change it:\nCODE>rubee start --port=3000\n\n4. Open your browser and navigate to http://localhost:3000/home.\n\n5. For development, run rubee start_dev in one terminal and rubee react watch in another. Changes apply instantly.\n\n6. In production, rebuild the React app with rubee react build. Not needed in development when using rubee react watch.\n\n7. Generate a React view from a route by specifying the view name:\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get('/', to: 'welcome#show')\nCODE>\nCODE> router.get('/api/users', to: 'user#index', react: { view_name: 'users.tsx' })\nCODE> # Note: /api/users is the backend endpoint.\nCODE> # To render /app/views/users.tsx, update the React routes as shown below.\nCODE>end\n\n8. Add logic to the generated API controller:\n\nCODE># app/controllers/api/user_controller.rb\nCODE>class Api::UserController\nCODE>\nCODE> } />\nCODE> } />\nCODE>\nCODE>\n\n10. Fetch data from the backend in the component:\n\nCODE>// app/views/users.tsx\nCODE>import { useState, useEffect } from 'react';\nCODE>\nCODE>function Users() {\nCODE> const [users, setUsers] = useState([]);\nCODE>\nCODE> useEffect(() => {\nCODE> fetch('/api/users')\nCODE> .then(response => response.json())\nCODE> .then(data => setUsers(data));\nCODE> }, []);\nCODE>\nCODE> return (\nCODE>\nCODE> Users\nCODE>\nCODE> {users.map(user => (\nCODE> id: {user.id}: {user.name}\nCODE> ))}\nCODE>\nCODE>\nCODE> );\nCODE>}","parent":"Views","vector":{"view":0.21779887175727827,"react":0.4632384515847269,"support":0.024199874639697586,"box":0.036923761003134443,"layer":0.04002936358407276,"prerequisites":0.036923761003134443,"node":0.04002936358407276,"npm":0.04002936358407276,"requir":0.03088256343898179,"after":0.029441057424940846,"creating":0.04002936358407276,"project":0.034514868495599725,"bundling":0.04002936358407276,"install":0.02703216491740613,"dependency":0.03088256343898179,"code":0.5923233630839385,"prepare":0.036923761003134443,"configure":0.028169559008623904,"config":0.13001633404114132,"base_configurate":0.028169559008623904,"base":0.02265506392015087,"configurate":0.052006533616456525,"setup":0.026003266808228263,"env":0.07519186928305674,"development":0.09679949855879035,"database_url":0.03088256343898179,"database":0.024199874639697586,"url":0.052006533616456525,"sqlite":0.029441057424940846,"register":0.04002936358407276,"true":0.02703216491740613,"end":0.039098922678425074,"start":0.08521558132625742,"server":0.02265506392015087,"default":0.0233998598607882,"port":0.07384752200626889,"7000":0.036923761003134443,"change":0.04002936358407276,"3000":0.08005872716814552,"open":0.03254666000587917,"browser":0.036923761003134443,"navigate":0.04002936358407276,"http":0.024199874639697586,"localhost":0.029441057424940846,"home":0.04002936358407276,"start_dev":0.03088256343898179,"dev":0.03088256343898179,"one":0.026003266808228263,"terminal":0.036923761003134443,"watch":0.07384752200626889,"another":0.04002936358407276,"changes":0.034514868495599725,"app":0.11327531960075433,"instant":0.04002936358407276,"producte":0.029441057424940846,"rebuild":0.04002936358407276,"build":0.03254666000587917,"not":0.028169559008623904,"need":0.03088256343898179,"generate":0.02265506392015087,"route":0.03088256343898179,"specifying":0.04002936358407276,"name":0.07519186928305674,"routes":0.052006533616456525,"router":0.10812865966962452,"draw":0.028169559008623904,"welcome":0.034514868495599725,"api":0.20708921097359836,"user":0.31955842997346534,"index":0.026003266808228263,"view_name":0.04002936358407276,"tsx":0.1200880907522183,"backend":0.08005872716814552,"endpoint":0.034514868495599725,"render":0.03088256343898179,"update":0.02703216491740613,"shown":0.04002936358407276,"below":0.04002936358407276,"add":0.0233998598607882,"logic":0.03254666000587917,"generat":0.03254666000587917,"controller":0.07259962391909276,"user_controller":0.04002936358407276,"clas":0.020103185754770294,"usercontroller":0.04002936358407276,"fetch":0.08005872716814552,"data":0.08832317227482255,"component":0.04002936358407276,"import":0.04002936358407276,"usestate":0.08005872716814552,"useeffect":0.08005872716814552,"functe":0.04002936358407276,"const":0.036923761003134443,"setuser":0.08005872716814552,"then":0.06509332001175834,"response":0.052006533616456525,"json":0.02506395642768558,"return":0.04002936358407276,"map":0.04002936358407276}},{"label":"Object hooks","body":"By including the Hookable module, any Ruby object can be charged with hooks — logic that executes before, after, or around a specific method call.\n\nBaseController is Hookable by default:\n\nCODE>class ApplesController { puts \"after index\" }, if: -> { true } # or use a lambda\nCODE> after :index, -> { puts \"after index2\" }, unless: -> { false } # if/unless guards accept a method or lambda\nCODE> around :index, :log\nCODE>\nCODE> def index\nCODE> response_with object: { test: \"hooks\" }\nCODE> end\nCODE>\nCODE> def print_hello\nCODE> puts \"hello!\"\nCODE> end\nCODE>\nCODE> def log\nCODE> puts \"before log around\"\nCODE> res = yield\nCODE> puts \"after log around\"\nCODE> res\nCODE> end\nCODE>end\n\nThe server logs will show the following execution stack:\n\nCODE>before log around\nCODE>hello!\nCODE>after index\nCODE>after index2\nCODE>after log around\nCODE>127.0.0.1 - - [17/Feb/2025:11:42:14 -0500] \"GET /apples HTTP/1.1\" 401 - 0.0359\n\nStarting from version 1.11, hooks can also be pinned to class methods:\n\nCODE>class AnyClass\nCODE> include Rubee::Hookable\nCODE> before :print_world, :print_hello, class_methods: true\nCODE>\nCODE> class << self\nCODE> def print_world\nCODE> puts \"world!\"\nCODE> end\nCODE>\nCODE> def print_hello\nCODE> puts \"hello!\"\nCODE> end\nCODE> end\nCODE>end\n\nOutput:\n\nCODE>hello!\nCODE>world!","parent":null,"vector":{"object":0.08143021633345049,"hook":0.12894655841073227,"including":0.041784490135805416,"hookable":0.13906052820705675,"module":0.036028206622971085,"any":0.0261629100826771,"ruby":0.028217416596406926,"charg":0.0385427193757881,"logic":0.03397370010924125,"executes":0.04635350940235225,"before":0.1128696663856277,"after":0.24585543479379146,"around":0.25070694081483247,"specific":0.0271434054444835,"method":0.1128696663856277,"call":0.0385427193757881,"basecontroller":0.03397370010924125,"default":0.024425849576118916,"code":0.5281264321493304,"clas":0.1049231478667188,"applescontroller":0.041784490135805416,"put":0.26979903563051666,"index":0.1357170272224175,"true":0.05643483319281385,"lambda":0.0927070188047045,"index2":0.0927070188047045,"unles":0.0679474002184825,"false":0.03397370010924125,"guard":0.041784490135805416,"accept":0.04635350940235225,"log":0.3244745658164658,"def":0.1263047089227904,"response_with":0.029404680842694417,"response":0.0271434054444835,"test":0.022237985434526656,"end":0.1632530125587421,"print_hello":0.13906052820705675,"print":0.20892245067902704,"hello":0.2924914309506379,"res":0.0927070188047045,"yield":0.04635350940235225,"server":0.02364839732986009,"execute":0.041784490135805416,"stack":0.041784490135805416,"127":0.041784490135805416,"feb":0.04635350940235225,"2025":0.041784490135805416,"0500":0.04635350940235225,"apples":0.029404680842694417,"http":0.02526094178455808,"401":0.04635350940235225,"0359":0.04635350940235225,"starting":0.03397370010924125,"version":0.03223663960268307,"pinn":0.04635350940235225,"anyclas":0.04635350940235225,"include":0.024425849576118916,"print_world":0.0927070188047045,"world":0.185414037609409,"class_method":0.04635350940235225,"self":0.04635350940235225,"output":0.03397370010924125}},{"label":"Validations","body":"Any class can be charged with validations by including the Validatable module.\nru.Bee models are validatable by default — no need to include it explicitly.\n\nCODE>class Foo\nCODE> include Rubee::Validatable\nCODE>\nCODE> attr_accessor :name, :age\nCODE>\nCODE> def initialize(name, age)\nCODE> @name = name\nCODE> @age = age\nCODE> end\nCODE>\nCODE> validate do\nCODE> attribute(:name).required.type(String).condition(->{ name.length > 2 })\nCODE>\nCODE> attribute(:age)\nCODE> .required('Age is a mandatory field')\nCODE> .type(Integer, error_message: 'Must be an integer!')\nCODE> .condition(->{ age > 18 }, fancy_error: 'You must be at least 18 years old!')\nCODE> end\nCODE>end\n\nCODE>irb(main):041> Foo.new(\"Test\", 20).valid?\nCODE>=> true\nCODE>irb(main):042> Foo.new(\"Test\", 1).errors\nCODE>=> {age: {fancy_error: \"You must be at least 18 years old!\"}}\nCODE>irb(main):046> Foo.new(\"Joe\", \"wrong\").valid?\nCODE>=> false\nCODE>irb(main):047> Foo.new(\"Joe\", \"wrong\").errors\nCODE>=> {age: {error_message: \"Must be an integer!\"}}\n\nModel example with persistence guards:\n\nCODE>class User { email.match?(/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z/i) }, error: 'Wrong email format'\nCODE> )\nCODE> end\nCODE>end\n\nCODE>irb(main):077> user.save\nCODE>=> {email: {error: \"Wrong email format\"}} (Rubee::Validatable::Error)\nCODE>irb(main):078> user.email = \"ok@ok.com\"\nCODE>irb(main):080> user.save\nCODE>=> true\n\nTo apply validate_before_persist! and validate_after_setters globally, add an initializer such as init/sequel_object_preloader.rb:\n\nCODE>Rubee::SequelObject.validate_before_persist!\nCODE>Rubee::SequelObject.validate_after_setters","parent":null,"vector":{"validate":0.299014366169385,"any":0.024110012924536333,"clas":0.05801415308516272,"charg":0.03551842892707529,"including":0.038505831118781475,"validatable":0.1708653520967914,"module":0.033201219764266196,"model":0.0376108031400421,"default":0.022509252491867596,"ne":0.029707161588990165,"include":0.04501850498373519,"explicit":0.038505831118781475,"code":0.4510752915123607,"foo":0.21358169012098926,"attr_accessor":0.038505831118781475,"attr":0.038505831118781475,"accessor":0.038505831118781475,"name":0.144660077547218,"age":0.3844470422177807,"def":0.02327881841075897,"initialize":0.033201219764266196,"end":0.09402700785010527,"attribute":0.07103685785415058,"requir":0.05941432317798033,"type":0.04501850498373519,"string":0.02832051982995271,"condite":0.0854326760483957,"length":0.04271633802419785,"mandatory":0.03551842892707529,"field":0.03551842892707529,"integer":0.09392376606497671,"error_message":0.0854326760483957,"error":0.2673644543009115,"message":0.07103685785415058,"must":0.1708653520967914,"fancy_error":0.0854326760483957,"fancy":0.0854326760483957,"least":0.0854326760483957,"year":0.0854326760483957,"old":0.0854326760483957,"irb":0.248629002489527,"main":0.19824363880966894,"041":0.04271633802419785,"new":0.10005429121063023,"test":0.040986122304268256,"valid":0.0854326760483957,"true":0.052006621334287254,"042":0.04271633802419785,"046":0.04271633802419785,"joe":0.0854326760483957,"wrong":0.14207371570830116,"false":0.0313079220216589,"047":0.04271633802419785,"persistence":0.03551842892707529,"guard":0.038505831118781475,"user":0.08197224460853651,"email":0.12055006462268167,"match":0.038505831118781475,"format":0.0854326760483957,"077":0.04271633802419785,"save":0.07103685785415058,"078":0.04271633802419785,"com":0.025013572802657556,"080":0.04271633802419785,"app":0.021792803761727247,"validate_before_persist":0.0854326760483957,"before":0.052006621334287254,"persist":0.07103685785415058,"validate_after_setter":0.0854326760483957,"after":0.05664103965990542,"setter":0.0854326760483957,"global":0.038505831118781475,"add":0.022509252491867596,"initializer":0.04271633802419785,"such":0.04271633802419785,"init":0.038505831118781475,"sequel_object_preloader":0.04271633802419785,"sequel":0.029707161588990165,"object":0.025013572802657556,"preloader":0.04271633802419785,"sequelobject":0.07103685785415058}},{"label":"Rubee support","body":"An optional set of useful methods can be added to base Ruby classes globally via configuration:\n\nCODE># Include all support methods\nCODE>Rubee::Configuration.setup do |config|\nCODE> config.rubee_support = { all: true }\nCODE>end\nCODE>\nCODE># Include only methods for a specific class\nCODE>Rubee::Configuration.setup do |config|\nCODE> config.rubee_support = { classes: [Rubee::Support::String] }\nCODE>end\n\nAvailable extensions:\n\nCODE># Hash — tolerates string or symbol keys interchangeably\nCODE>{one: 1}[:one] # => 1\nCODE>{one: 1}[\"one\"] # => 1\nCODE>\nCODE># Hash — deep digging\nCODE>{one: {two: 2}}.deep_dig(:two) # => 2\n\nCODE># String — enriched with helper methods\nCODE>\"test\".pluralize # => \"tests\"\nCODE>\"test\".singularize # => \"test\"\nCODE>\"test\".camelize # => \"Test\"\nCODE>\"TestMe\".snakeize # => \"test_me\"\nCODE>\"test\".singular? # => true\nCODE>\"test\".plural? # => false","parent":null,"vector":{"support":0.23218394742087192,"optional":0.06623008202591897,"useful":0.08521092270936428,"method":0.20748652135774198,"add":0.04490165269418862,"base":0.04347247453442622,"ruby":0.051871630339435496,"classes":0.17042184541872857,"global":0.07681176690435501,"configurate":0.14969187791085242,"code":0.5209420038389959,"include":0.08980330538837723,"all":0.08980330538837723,"setup":0.09979458527390163,"config":0.19958917054780326,"rubee_support":0.17042184541872857,"true":0.10374326067887099,"end":0.07502635730590404,"on":0.07085247102288081,"specific":0.049897292636950814,"clas":0.038575712426384176,"string":0.16948205800919205,"available":0.05405415941286228,"extension":0.07085247102288081,"hash":0.14170494204576162,"tolerates":0.08521092270936428,"symbol":0.08521092270936428,"key":0.05649401933639735,"interchangeab":0.08521092270936428,"one":0.24948646318475406,"deep":0.17042184541872857,"digging":0.08521092270936428,"two":0.17042184541872857,"deep_dig":0.08521092270936428,"dig":0.08521092270936428,"enrich":0.08521092270936428,"helper":0.08521092270936428,"test":0.36791763002512473,"pluralize":0.08521092270936428,"singularize":0.08521092270936428,"camelize":0.08521092270936428,"testme":0.08521092270936428,"snakeize":0.08521092270936428,"test_me":0.08521092270936428,"singular":0.08521092270936428,"plural":0.08521092270936428,"false":0.06245331521787154}},{"label":"JWT based authentication","body":"Include the AuthTokenable module in your controller and authenticate any action you need.\n\nFirst, initialize the User model:\n\nCODE>rubee db run:create_users\n\nThis creates the users table and seeds it with demo credentials — email ok@ok.com, password password. Customize /db/create_users.rb before running the migration if needed.\n\nCODE>class UsersController < Rubee::BaseController\nCODE> include Rubee::AuthTokenable\nCODE> auth_methods :index # unauthenticated requests to these actions will be rejected\nCODE>\nCODE> # GET /users/login\nCODE> def edit\nCODE> response_with\nCODE> end\nCODE>\nCODE> # POST /users/login\nCODE> def login\nCODE> if authenticate! # initializes @token_header\nCODE> response_with type: :redirect, to: \"/users\", headers: @token_header\nCODE> else\nCODE> @error = \"Wrong email or password\"\nCODE> response_with render_view: \"users_edit\"\nCODE> end\nCODE> end\nCODE>\nCODE> # POST /users/logout\nCODE> def logout\nCODE> unauthenticate!\nCODE> response_with type: :redirect, to: \"/users/login\", headers: @zeroed_token_header\nCODE> end\nCODE>\nCODE> # GET /users (restricted)\nCODE> def index\nCODE> response_with object: User.all, type: :json\nCODE> end\nCODE>end\n\nSet a JWT_KEY at startup for security:\n\nCODE>JWT_KEY=SDJwer0wer23j rubee start\n\nTo use a custom model instead of the default User, pass arguments to authenticate! and unauthenticate!:\n\nCODE>if authenticate! user_model: Client, login: :name, password: :digest_password\nCODE> response_with type: :redirect, to: \"/clients\", headers: @token_header\nCODE>end","parent":null,"vector":{"jwt":0.12097248393002186,"bas":0.04032416131000728,"authenticat":0.03802467821502357,"include":0.05467670976514276,"authtokenable":0.09353363258543884,"module":0.04032416131000728,"controller":0.02827302235781454,"authenticate":0.18706726517087768,"any":0.02928254013732772,"acte":0.036080492960267226,"ne":0.036080492960267226,"first":0.031582023232311435,"initialize":0.04032416131000728,"user":0.34845457886865383,"model":0.06851965546384675,"code":0.504597146498903,"create_user":0.10376127848859604,"create":0.05293640056146567,"creates":0.05188063924429802,"table":0.04676681629271942,"seed":0.05188063924429802,"demo":0.04676681629271942,"credential":0.05188063924429802,"email":0.05856508027465544,"com":0.03037994844151977,"password":0.15189974220759886,"customize":0.05188063924429802,"before":0.031582023232311435,"running":0.034396363088906326,"migrate":0.034396363088906326,"need":0.036080492960267226,"clas":0.023486808455426857,"userscontroller":0.04676681629271942,"basecontroller":0.03802467821502357,"auth_method":0.05188063924429802,"auth":0.04313850116660217,"method":0.031582023232311435,"index":0.06075989688303954,"unauthenticat":0.05188063924429802,"request":0.04676681629271942,"action":0.05188063924429802,"reject":0.05188063924429802,"login":0.2338340814635971,"def":0.11309208943125816,"edit":0.09353363258543884,"response_with":0.1974651315806698,"response":0.18227969064911861,"end":0.1598791960823091,"post":0.06879272617781265,"initializes":0.05188063924429802,"token_header":0.14030044887815826,"token":0.18706726517087768,"header":0.3273677140490359,"type":0.10935341953028552,"redirect":0.14030044887815826,"else":0.04676681629271942,"error":0.036080492960267226,"wrong":0.04313850116660217,"render_view":0.04676681629271942,"render":0.036080492960267226,"view":0.02827302235781454,"users_edit":0.04676681629271942,"logout":0.09353363258543884,"unauthenticate":0.09353363258543884,"zeroed_token_header":0.04676681629271942,"zero":0.04676681629271942,"restrict":0.05188063924429802,"object":0.03037994844151977,"all":0.02733835488257138,"json":0.02928254013732772,"jwt_key":0.10376127848859604,"key":0.06879272617781265,"startup":0.05188063924429802,"security":0.05188063924429802,"sdjwer0wer23j":0.05188063924429802,"start":0.024889612776332417,"custom":0.03802467821502357,"instead":0.05188063924429802,"default":0.02733835488257138,"pas":0.04032416131000728,"argument":0.04313850116660217,"user_model":0.05188063924429802,"client":0.08064832262001456,"name":0.02928254013732772,"digest_password":0.05188063924429802,"digest":0.05188063924429802}},{"label":"OAuth authentication","body":"To plug in OAuth 2.0 authentication, add the oauth2 gem to your Gemfile:\n\nCODE>gem 'oauth2'\n\nUse the following as a starting point:\n\nCODE>class UsersController < Rubee::BaseController\nCODE> include Rubee::AuthTokenable\nCODE>\nCODE> REDIRECT_URI = 'https://mysite.com/users/oauth_callback'\nCODE> CLIENT_ID = ENV['GOOGLE_CLIENT_ID']\nCODE> CLIENT_SECRET = ENV['GOOGLE_CLIENT_SECRET']\nCODE>\nCODE> # GET /login\nCODE> def edit\nCODE> response_with\nCODE> end\nCODE>\nCODE> # POST /users/login\nCODE> def login\nCODE> if authenticate!\nCODE> response_with(type: :redirect, to: \"/sections\", headers: @token_header)\nCODE> else\nCODE> @error = \"Wrong email or password\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE> end\nCODE>\nCODE> # GET /users/oauth_login\nCODE> def oauth_login\nCODE> response_with(\nCODE> type: :redirect,\nCODE> to: auth_client.auth_code.authorize_url(\nCODE> redirect_uri: REDIRECT_URI,\nCODE> scope: 'email profile openid'\nCODE> )\nCODE> )\nCODE> end\nCODE>\nCODE> # GET /users/oauth_callback\nCODE> def oauth_callback\nCODE> code = params[:code]\nCODE> token = auth_client.auth_code.get_token(code, redirect_uri: REDIRECT_URI)\nCODE> user_info = JSON.parse(token.get('https://www.googleapis.com/oauth2/v1/userinfo?alt=json').body)\nCODE>\nCODE> user = User.where(email: user_info['email'])&.last\nCODE> raise \"User with email #{user_info['email']} not found\" unless user\nCODE>\nCODE> params[:email] = user_info['email']\nCODE> params[:password] = user.password\nCODE>\nCODE> if authenticate!\nCODE> response_with(type: :redirect, to: \"/sections\", headers: @token_header)\nCODE> else\nCODE> @error = \"Something went wrong\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE> rescue OAuth2::Error\nCODE> @error = \"OAuth login failed\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> rescue StandardError\nCODE> @error = \"Something went wrong\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE>\nCODE> # POST /users/logout\nCODE> def logout\nCODE> unauthenticate!\nCODE> response_with(type: :redirect, to: \"/login\", headers: @zeroed_token_header)\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def auth_client\nCODE> @client ||= OAuth2::Client.new(\nCODE> CLIENT_ID,\nCODE> CLIENT_SECRET,\nCODE> site: 'https://accounts.google.com',\nCODE> authorize_url: '/o/oauth2/auth',\nCODE> token_url: 'https://oauth2.googleapis.com/token'\nCODE> )\nCODE> end\nCODE>end","parent":null,"vector":{"oauth":0.21136340174618293,"authenticat":0.038728442126484935,"plug":0.02381619021192569,"add":0.01392216771586842,"oauth2":0.18494297652791003,"gem":0.035032973841812844,"gemfile":0.019364221063242468,"code":0.6093815802665591,"starting":0.019364221063242468,"point":0.026420425218272866,"clas":0.01196075213126261,"userscontroller":0.02381619021192569,"basecontroller":0.019364221063242468,"include":0.01392216771586842,"authtokenable":0.02381619021192569,"redirect_uri":0.13210212609136432,"redirect":0.2143457119073312,"uri":0.13210212609136432,"http":0.057592603620919634,"mysite":0.026420425218272866,"com":0.0618844461152143,"user":0.2281524462237691,"oauth_callback":0.0792612756548186,"callback":0.0792612756548186,"client_id":0.05284085043654573,"client":0.22588766335362415,"env":0.029824503829118495,"google_client_id":0.026420425218272866,"google":0.0792612756548186,"client_secret":0.05284085043654573,"secret":0.0792612756548186,"google_client_secret":0.026420425218272866,"login":0.16671333148347983,"def":0.08638890543137945,"edit":0.11908095105962845,"response_with":0.15083987451205763,"response":0.13924000375923215,"end":0.10468173443121265,"post":0.035032973841812844,"authenticate":0.04763238042385138,"type":0.05568867086347368,"section":0.05284085043654573,"header":0.14289714127155415,"token_header":0.04763238042385138,"token":0.19052952169540552,"else":0.04763238042385138,"error":0.09187068432275819,"wrong":0.06590536820876892,"email":0.11929801531647398,"password":0.046413334586410726,"render_view":0.09526476084770276,"render":0.07349654745820655,"view":0.057592603620919634,"users_edit":0.09526476084770276,"oauth_login":0.05284085043654573,"auth_client":0.0792612756548186,"auth":0.13181073641753785,"auth_code":0.05284085043654573,"authorize_url":0.05284085043654573,"authorize":0.05284085043654573,"url":0.046413334586410726,"scope":0.026420425218272866,"profile":0.026420425218272866,"openid":0.026420425218272866,"param":0.06590536820876892,"get_token":0.026420425218272866,"user_info":0.10568170087309146,"info":0.09526476084770276,"json":0.029824503829118495,"parse":0.026420425218272866,"www":0.026420425218272866,"googleapis":0.05284085043654573,"userinfo":0.026420425218272866,"alt":0.026420425218272866,"body":0.026420425218272866,"last":0.020535242123056744,"raise":0.026420425218272866,"not":0.016759986056895295,"found":0.026420425218272866,"unles":0.019364221063242468,"something":0.04393691213917929,"went":0.05284085043654573,"rescue":0.04763238042385138,"fail":0.026420425218272866,"standarderror":0.02381619021192569,"logout":0.04763238042385138,"unauthenticate":0.02381619021192569,"zeroed_token_header":0.02381619021192569,"zero":0.02381619021192569,"private":0.026420425218272866,"new":0.015471111528803575,"site":0.02381619021192569,"account":0.02381619021192569,"token_url":0.026420425218272866}},{"label":"ru.Bee commands","body":"CODE>rubee start # start the server\nCODE>rubee start_dev # start the server in dev mode, restarting on file changes\nCODE>rubee react prepare # install React dependencies\nCODE>rubee react watch # React dev mode, use together with start_dev\nCODE>rubee stop # stop the server\nCODE>rubee restart # restart the server","parent":null,"vector":{"command":0.08676633916544528,"code":0.2470541980166487,"start":0.35542861239626,"server":0.30237692431608526,"start_dev":0.20609464136999694,"dev":0.4121892827399939,"mode":0.20609464136999694,"restarting":0.14817316591093213,"file":0.08363209746955187,"changes":0.11516740601193694,"react":0.4121892827399939,"prepare":0.12320527240246751,"install":0.0901995125034723,"dependency":0.10304732068499847,"watch":0.12320527240246751,"together":0.14817316591093213,"stop":0.29634633182186426,"restart":0.29634633182186426}},{"label":"Generate commands","body":"CODE>rubee generate get /apples # generate controller, view, model, and migration if set in routes\nCODE>rubee gen get /apples # shorthand alias","parent":null,"vector":{"generate":0.531089712586369,"command":0.20319323962423336,"code":0.19285413883084038,"apples":0.44024191236903243,"controller":0.18910127572834443,"view":0.18910127572834443,"model":0.15276228220549315,"migrate":0.2300566263560336,"routes":0.20319323962423336,"gen":0.2300566263560336,"shorthand":0.34699845465892093,"alias":0.28852754050747725}},{"label":"Migration commands","body":"CODE>rubee db run:all # run all migrations\nCODE>rubee db run:create_apples # run a specific migration file from /db\nCODE>rubee db structure # generate a migration file for the database structure","parent":null,"vector":{"migrate":0.683840493061615,"command":0.15099735157854363,"code":0.21497120862586527,"all":0.2717594594822242,"create_apples":0.20042303804951683,"create":0.13155480336428083,"apples":0.16357670891150347,"specific":0.15099735157854363,"file":0.29108581383805,"structure":0.40084607609903367,"generate":0.13155480336428083,"database":0.14052530422719114}},{"label":"ru.Bee console","body":"CODE>rubee console # start the interactive console\nCODE># type 'reload' inside the console to pick up the latest changes\n\nTo run any ru.Bee command in a specific environment, prefix with the env variable:\n\nCODE>RACK_ENV=test rubee console","parent":null,"vector":{"console":0.7977597561768759,"code":0.1475578486025834,"start":0.08491461678940478,"interactive":0.12309396939301702,"type":0.09326886478176753,"reload":0.13757187529447645,"inside":0.1471734144017923,"pick":0.17699851901304178,"latest":0.1595519512353752,"changes":0.13757187529447645,"any":0.09990174201287617,"command":0.10364571370296967,"specific":0.10364571370296967,"environment":0.11228027884645908,"prefix":0.17699851901304178,"env":0.19980348402575235,"variable":0.17699851901304178,"rack_env":0.1471734144017923,"rack":0.13757187529447645,"test":0.08491461678940478}},{"label":"Testing","body":"CODE>rubee test # run all tests\nCODE>rubee test auth_tokenable_test.rb # run a specific test file\nCODE>rubee test models/user_model_test.rb --line=12 # run a specific line","parent":null,"vector":{"testing":0.21385109505157004,"code":0.17828063016047693,"test":0.7181618649290756,"all":0.11268822461914581,"auth_tokenable_test":0.21385109505157004,"auth":0.1778161535350629,"tokenable":0.21385109505157004,"specific":0.25045124102025307,"file":0.12070212251571914,"model":0.1882912208605239,"user_model_test":0.19277200554873342,"user":0.10259455213272507,"line":0.3324309869265525}},{"label":"Background jobs","body":"Sidekiq engine\n\n1. Add Sidekiq to your Gemfile\n\nCODE>gem 'sidekiq'\n\n2. Configure the adapter for the desired environment\n\nCODE># config/base_configuration.rb\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"sqlite://db/development.db\", env: }\nCODE> config.async_adapter = { async_adapter: SidekiqAsync, env: }\nCODE>end\n\n3. Install dependencies\n\nCODE>bundle install\n\n4. Start Redis\n\nCODE>redis-server\n\n5. Add a Sidekiq configuration file\n\nCODE># config/sidekiq.yml\nCODE>\nCODE>development:\nCODE> redis: redis://localhost:6379/0\nCODE> concurrency: 5\nCODE> queues:\nCODE> default:\nCODE> low:\nCODE> high:\n\n6. Create a Sidekiq worker\n\nCODE># app/async/test_async_runner.rb\nCODE>require_relative 'extensions/asyncable' unless defined? Asyncable\nCODE>\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :default\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\n\n7. Use it in your codebase\n\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })\n\nDefault engine — ThreadAsync\n\nThe default adapter is ThreadAsync. It is not yet recommended for production — use with caution.\n\n1. Do not define any adapter in config/base_configuration.rb; the default ThreadAsync will be used.\n2. Create a worker and process it:\n\nCODE># test_async_runner.rb\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\nCODE>\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })","parent":null,"vector":{"background":0.036839065186002905,"job":0.036839065186002905,"sidekiq":0.3417992068237765,"engine":0.07367813037200581,"add":0.04995116599472536,"gemfile":0.03473831950702969,"code":0.5400125591595683,"gem":0.0314235887574227,"configure":0.0300664689106943,"adapter":0.18419532593001453,"desir":0.03941017010336508,"environment":0.0300664689106943,"config":0.1665258045736677,"base_configurate":0.0601329378213886,"base":0.04836126648745028,"configurate":0.1110172030491118,"setup":0.02775430076227795,"env":0.08025521448326195,"development":0.07748840991167977,"database_url":0.03296216434330505,"database":0.02582946997055992,"url":0.0555086015245559,"sqlite":0.0314235887574227,"async_adapter":0.08544980170594413,"async":0.25787345630202035,"sidekiqasync":0.042724900852972064,"end":0.10432951247059075,"install":0.05770496768012105,"dependency":0.03296216434330505,"bundle":0.03941017010336508,"start":0.022738478315087247,"redis":0.15764068041346033,"server":0.02418063324372514,"file":0.026751738161087314,"yml":0.042724900852972064,"localhost":0.0314235887574227,"6379":0.03941017010336508,"concurrency":0.042724900852972064,"queues":0.042724900852972064,"default":0.1248779149868134,"low":0.03941017010336508,"high":0.042724900852972064,"create":0.09672253297490056,"worker":0.11823051031009525,"app":0.02418063324372514,"test_async_runner":0.07882034020673016,"test":0.045476956630174495,"runner":0.07882034020673016,"require_relative":0.042724900852972064,"require":0.042724900852972064,"relative":0.042724900852972064,"extension":0.03941017010336508,"asyncable":0.14735626074401162,"unles":0.03473831950702969,"defin":0.036839065186002905,"clas":0.04291382831493182,"testasyncrunner":0.15764068041346033,"include":0.07492674899208804,"sidekiq_option":0.042724900852972064,"option":0.25967235456054477,"queue":0.042724900852972064,"def":0.05165893994111984,"perform":0.15764068041346033,"user":0.045476956630174495,"email":0.1605104289665239,"password":0.1665258045736677,"codebase":0.042724900852972064,"new":0.1665258045736677,"perform_async":0.07882034020673016,"com":0.0555086015245559,"123":0.0628471775148454,"threadasync":0.1281747025589162,"not":0.0601329378213886,"yet":0.042724900852972064,"recommend":0.03941017010336508,"producte":0.0314235887574227,"caute":0.042724900852972064,"define":0.03473831950702969,"any":0.026751738161087314,"us":0.03941017010336508,"proces":0.03941017010336508}},{"label":"Background jobs — Sidekiq engine","body":"1. Add Sidekiq to your Gemfile\n\nCODE>gem 'sidekiq'\n\n2. Configure the adapter for the desired environment\n\nCODE># config/base_configuration.rb\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"sqlite://db/development.db\", env: }\nCODE> config.async_adapter = { async_adapter: SidekiqAsync, env: }\nCODE>end\n\n3. Install dependencies\n\nCODE>bundle install\n\n4. Start Redis\n\nCODE>redis-server\n\n5. Add a Sidekiq configuration file\n\nCODE># config/sidekiq.yml\nCODE>\nCODE>development:\nCODE> redis: redis://localhost:6379/0\nCODE> concurrency: 5\nCODE> queues:\nCODE> default:\nCODE> low:\nCODE> high:\n\n6. Create a Sidekiq worker\n\nCODE># app/async/test_async_runner.rb\nCODE>require_relative 'extensions/asyncable' unless defined? Asyncable\nCODE>\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :default\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\n\n7. Use it in your codebase\n\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })","parent":"Background jobs","vector":{"background":0.04971318032179236,"job":0.04971318032179236,"sidekiq":0.4612474696869379,"engine":0.04971318032179236,"add":0.06740755526345643,"gemfile":0.04687828893077243,"code":0.5509911758562404,"gem":0.0424051621931262,"configure":0.04057377088832386,"adapter":0.1491395409653771,"desir":0.05318280697322101,"environment":0.04057377088832386,"config":0.18726785703354712,"base_configurate":0.04057377088832386,"base":0.03263101749924898,"configurate":0.11236071422012826,"setup":0.03745357140670942,"env":0.1083019324520329,"development":0.10456821516339536,"database_url":0.04448142241182301,"database":0.03485607172113178,"url":0.07490714281341884,"sqlite":0.0424051621931262,"async_adapter":0.11531186742173448,"async":0.24856590160896183,"sidekiqasync":0.05765593371086724,"end":0.08447367228480825,"install":0.07787107108339511,"dependency":0.04448142241182301,"bundle":0.05318280697322101,"start":0.03068487397857741,"redis":0.21273122789288404,"server":0.03263101749924898,"file":0.03610064415067763,"yml":0.05765593371086724,"localhost":0.0424051621931262,"6379":0.05318280697322101,"concurrency":0.05765593371086724,"queues":0.05765593371086724,"default":0.06740755526345643,"low":0.05318280697322101,"high":0.05765593371086724,"create":0.06526203499849796,"worker":0.10636561394644202,"app":0.03263101749924898,"test_async_runner":0.05318280697322101,"test":0.03068487397857741,"runner":0.05318280697322101,"require_relative":0.05765593371086724,"require":0.05765593371086724,"relative":0.05765593371086724,"extension":0.05318280697322101,"asyncable":0.1491395409653771,"unles":0.04687828893077243,"defin":0.04971318032179236,"clas":0.02895544274192425,"testasyncrunner":0.10636561394644202,"include":0.06740755526345643,"sidekiq_option":0.05765593371086724,"option":0.19467767770848776,"queue":0.05765593371086724,"def":0.03485607172113178,"perform":0.10636561394644202,"user":0.03068487397857741,"email":0.1083019324520329,"password":0.11236071422012826,"codebase":0.05765593371086724,"new":0.11236071422012826,"perform_async":0.05318280697322101,"com":0.03745357140670942,"123":0.0424051621931262}},{"label":"Background jobs — Default engine — ThreadAsync","body":"The default adapter is ThreadAsync. It is not yet recommended for production — use with caution.\n\n1. Do not define any adapter in config/base_configuration.rb; the default ThreadAsync will be used.\n2. Create a worker and process it:\n\nCODE># test_async_runner.rb\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\nCODE>\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })","parent":"Background jobs","vector":{"background":0.10047615056227796,"job":0.10047615056227796,"default":0.2043578270745986,"engine":0.10047615056227796,"threadasync":0.349588151804625,"adapter":0.20095230112455592,"not":0.16400867078976764,"yet":0.11652938393487498,"recommend":0.10748867174010769,"producte":0.08570579137272845,"caute":0.11652938393487498,"define":0.09474650356749575,"any":0.07296362320011651,"config":0.07569804738696079,"base_configurate":0.08200433539488382,"base":0.06595110202228678,"configurate":0.07569804738696079,"us":0.10748867174010769,"create":0.13190220404457356,"worker":0.10748867174010769,"proces":0.10748867174010769,"code":0.35923148247909015,"test_async_runner":0.10748867174010769,"test":0.06201771839780198,"async":0.20095230112455592,"runner":0.10748867174010769,"clas":0.05852233564022577,"testasyncrunner":0.21497734348021538,"include":0.06811927569153287,"asyncable":0.10047615056227796,"def":0.07044819678790021,"perform":0.21497734348021538,"option":0.31477308077959487,"user":0.06201771839780198,"email":0.21889086960034956,"password":0.2270941421608824,"end":0.11382077965503894,"new":0.2270941421608824,"perform_async":0.10748867174010769,"com":0.07569804738696079,"123":0.08570579137272845}},{"label":"Logger","body":"Use your own logger by setting it in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"sqlite://db/development.db\", env: }\nCODE> config.logger = { logger: MyLogger, env: }\nCODE>end\n\nOr use the built-in logger with its full set of levels:\n\nCODE># app/controllers/welcome_controller.rb\nCODE>class WelcomeController (&target_method) do\nCODE> start = Time.now\nCODE> Rubee::Logger.warn(message: 'This is a warning message', method: :show, class_name: 'WelcomeController')\nCODE> Rubee::Logger.error(message: 'This is an error message', class_name: 'WelcomeController')\nCODE> Rubee::Logger.critical(message: 'We are on fire!')\nCODE> target_method.call\nCODE> Rubee::Logger.info(\nCODE> message: \"Execution Time: #{Time.now - start} seconds\",\nCODE> method: :show,\nCODE> class_name: 'WelcomeController'\nCODE> )\nCODE> Rubee::Logger.debug(object: User.last, method: :show, class_name: 'WelcomeController')\nCODE> end\nCODE>\nCODE> def show\nCODE> response_with\nCODE> end\nCODE>end\n\nOutput:\n\nCODE>[2025-04-26 12:32:33] WARN [method: show][class_name: WelcomeController] This is a warning message\nCODE>[2025-04-26 12:32:33] ERROR [class_name: WelcomeController] This is an error message\nCODE>[2025-04-26 12:32:33] CRITICAL We are on fire!\nCODE>[2025-04-26 12:32:33] INFO [method: show][class_name: WelcomeController] Execution Time: 0.000655 seconds\nCODE>[2025-04-26 12:32:33] DEBUG [method: show][class_name: WelcomeController] #","parent":null,"vector":{"logger":0.41400198991821563,"own":0.03366124464938255,"setting":0.04592719707694154,"config":0.10757507228782644,"base_configurate":0.029134246564262573,"base":0.023430903479061866,"configurate":0.05378753614391322,"code":0.35735461905303323,"setup":0.02689376807195661,"env":0.07776687092083062,"development":0.0500572347874775,"database_url":0.03194015985455531,"database":0.02502861739373875,"url":0.05378753614391322,"sqlite":0.030449288392063508,"mylogger":0.04592719707694154,"end":0.0808757888869713,"built":0.03366124464938255,"full":0.02795790156418184,"level":0.04592719707694154,"app":0.023430903479061866,"controller":0.0500572347874775,"welcome_controller":0.038188242734502525,"welcome":0.035696855906620854,"clas":0.1871247090856514,"welcomecontroller":0.3436941846105227,"target_method":0.09185439415388308,"target":0.08280039798364312,"method":0.22366321251345472,"start":0.04406692622905626,"time":0.1346449785975302,"now":0.09185439415388308,"warn":0.09185439415388308,"message":0.3055059418760202,"warning":0.09185439415388308,"class_name":0.3674175766155323,"name":0.2073783224555483,"error":0.12776063941822124,"critical":0.09185439415388308,"fire":0.09185439415388308,"call":0.038188242734502525,"info":0.08280039798364312,"execute":0.08280039798364312,"second":0.09185439415388308,"debug":0.07637648546900505,"object":0.02689376807195661,"user":0.02203346311452813,"last":0.035696855906620854,"def":0.02502861739373875,"response_with":0.029134246564262573,"response":0.02689376807195661,"output":0.03366124464938255,"2025":0.20700099495910781,"000655":0.04592719707694154}},{"label":"WebSocket","body":"With ru.Bee 2.0.0 you can use WebSocket with ease.\n\n1. Install and start Redis\n\nCODE>sudo apt-get install -y redis # Linux\nCODE>brew install redis # macOS\n\n2. Add the required gems to your Gemfile\n\nCODE>gem 'ru.Bee'\nCODE>gem 'redis'\nCODE>gem 'websocket'\n\n3. Add the Redis URL to your configuration, unless it defaults to 127.0.0.1:6379\n\nCODE># config/base_configuration.rb\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> ...\nCODE> config.redis_url = { url: \"redis://localhost:6378/0\", env: }\nCODE>end\n\n4. Add a WebSocket entry route\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get('/ws', to: 'users#websocket')\nCODE> # On the client: const ws = new WebSocket(\"ws://website/ws\");\nCODE>end\n\n5. Make the model pub/sub capable\n\nCODE># app/models/user.rb\nCODE>class User e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>\nCODE> # Expected client params: { action: 'unsubscribe', channel: 'default', id: '123', subscriber: 'User' }\nCODE> def unsubscribe\nCODE> channel = params[:channel]\nCODE> sender_id = params[:options][:id]\nCODE> io = params[:options][:io]\nCODE>\nCODE> User.unsub(channel, sender_id, io) do |channel, args|\nCODE> websocket_connections.remove(channel, args[:io])\nCODE> end\nCODE> response_with(object: params.merge(type: 'system', status: :unsubscribed), type: :websocket)\nCODE> rescue StandardError => e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>\nCODE> # Expected client params: { action: 'publish', channel: 'default', message: 'Hello', id: '123', subscriber: 'User' }\nCODE> def publish\nCODE> args = {}\nCODE> User.pub(params[:channel], message: params[:message]) do |channel|\nCODE> user = User.find(params[:options][:id])\nCODE> args[:message] = params[:message]\nCODE> args[:sender] = params[:options][:id]\nCODE> args[:sender_name] = user.email\nCODE> websocket_connections.stream(channel, args)\nCODE> end\nCODE> response_with(object: { type: 'system', message: params[:message], status: :published }, type: :websocket)\nCODE> rescue StandardError => e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>end\n\nFor a full chat application example, see rubee-chat.","parent":null,"vector":{"websocket":0.3347685557962017,"ease":0.02986577361844802,"install":0.06050582214310056,"start":0.015894764697602447,"redis":0.1928408578022077,"code":0.460344239798606,"sudo":0.03313151395964903,"apt":0.03313151395964903,"linux":0.03313151395964903,"brew":0.03313151395964903,"macos":0.03313151395964903,"add":0.05237567036292646,"requir":0.02304137677554722,"gem":0.08786349593535554,"gemfile":0.02428295363054295,"url":0.058202849880704996,"configurate":0.058202849880704996,"unles":0.02428295363054295,"default":0.05237567036292646,"127":0.02986577361844802,"6379":0.02754869397174396,"config":0.07760379984093999,"base_configurate":0.021017213289341946,"base":0.01690286703983251,"setup":0.019400949960234996,"env":0.03740026728527576,"development":0.0180554451250782,"redis_url":0.03313151395964903,"localhost":0.021965873983838886,"6378":0.03313151395964903,"end":0.11668629914502755,"entry":0.03313151395964903,"route":0.02304137677554722,"routes":0.019400949960234996,"router":0.06050582214310056,"draw":0.021017213289341946,"user":0.15894764697602445,"client":0.07725428210681579,"const":0.02754869397174396,"new":0.019400949960234996,"website":0.03313151395964903,"model":0.029171574786256888,"pub":0.06626302791929806,"sub":0.03313151395964903,"capable":0.03313151395964903,"app":0.01690286703983251,"clas":0.014998919318329359,"response_with":0.10508606644670972,"response":0.09700474980117499,"object":0.09700474980117499,"type":0.1745855678764215,"system":0.1656575697982451,"error":0.06912413032664166,"message":0.27548693971743954,"expect":0.06626302791929806,"param":0.33058432766092755,"acte":0.04608275355109444,"unsubscribe":0.06626302791929806,"channel":0.3313151395964902,"123":0.04393174796767777,"subscriber":0.06626302791929806,"def":0.0361108902501564,"sender_id":0.06626302791929806,"sender":0.1325260558385961,"option":0.08067442952413408,"unsub":0.03313151395964903,"arg":0.2319205977175432,"websocket_connection":0.06626302791929806,"connection":0.05509738794348792,"remove":0.03313151395964903,"merge":0.03313151395964903,"status":0.06626302791929806,"unsubscrib":0.03313151395964903,"rescue":0.05973154723689604,"standarderror":0.05973154723689604,"publish":0.09939454187894708,"hello":0.02986577361844802,"find":0.025751427368938592,"sender_name":0.03313151395964903,"name":0.01870013364263788,"email":0.01870013364263788,"stream":0.03313151395964903,"full":0.02016860738103352,"chat":0.06626302791929806,"applicat":0.025751427368938592,"see":0.03313151395964903}},{"label":"Bee assistant","body":"ru.Bee ships with a built-in CLI assistant called bee. It answers questions about the framework directly in your terminal, using a local TF-IDF knowledge base built from the project documentation. Optionally, it routes answers through a local Ollama language model for richer, more conversational responses.\n\nNo external API keys or internet connection are required in the default mode.\n\nBuilding the knowledge base\n\nBefore using the assistant for the first time, generate the knowledge base from the README:\n\nCODE>rubee bee generate # or: rubee bee gen\n\nThis parses the documentation, computes TF-IDF vectors, and writes a bee_knowledge.json file to lib/rubee/cli/. Re-run this command any time the documentation is updated.\n\nInteractive mode\n\nStart an interactive session and ask questions conversationally:\n\nCODE>rubee bee\n\nCODE> ⬡ ⬢ ⬢ ru.Bee — domestic AI assistant\nCODE> ──────────────────────────────────────────────\nCODE> Ask me anything about the ru.Bee framework.\nCODE> Type exit to leave • rubee bee generate to retrain.\nCODE> You: How do I run the server?\n\nType exit, quit, bye, or q to leave the session.\n\nSingle-shot mode\n\nPass a question directly as a command-line argument to get one answer and exit:\n\nCODE>rubee bee how do hooks work\nCODE>rubee bee what databases are supported\nCODE>rubee bee how do I set up JWT authentication\n\nLLM mode\n\nIf you have Ollama installed and running locally, enable LLM mode for more detailed answers. The assistant retrieves the most relevant documentation and passes it as context to the model.\n\nCODE>rubee bee --llm # interactive mode, default model (qwen2.5:1.5b)\nCODE>rubee bee --llm=llama3.2 # interactive mode, specific model\nCODE>rubee bee --llm how do hooks work # single-shot LLM answer\nCODE>rubee bee --llm=qwen2.5:0.5b how do I configure WebSocket # single-shot with specific model\n\nIf the specified model is not available locally, the assistant automatically pulls it from Ollama before answering, displaying a live download progress bar.\n\nEnvironment options\n\nCODE>OLLAMA_URL=http://remote-host:11434 rubee bee --llm # use a custom Ollama endpoint\nCODE>BEE_KNOWLEDGE=/path/to/custom.json rubee bee # use a custom knowledge base file\nCODE>BEE_DEBUG=1 rubee bee --llm # write LLM debug output to /tmp/bee_ollama_debug.txt\n\nSuggestions\n\nAfter every answer, the assistant suggests up to five related topics you might want to explore next, along with a link to the full documentation at https://rubee.dedyn.io/.\n\nCommand reference\n\nCODE>rubee bee generate # build the knowledge base from the README\nCODE>rubee bee gen # alias for generate\nCODE>rubee bee # start interactive mode\nCODE>rubee bee # single-shot answer\nCODE>rubee bee --llm # interactive LLM mode (default model: qwen2.5:1.5b)\nCODE>rubee bee --llm= # interactive LLM mode with a specific Ollama model\nCODE>rubee bee --llm # single-shot LLM answer\nCODE>rubee bee --llm= # single-shot with a specific model\n\nContributing\n\nIf you are interested in contributing to ru.Bee, please read the Contributing guide.\nFeel free to open an issue if you spot one.\nHave an idea or want to discuss something? Open a discussion.","parent":null,"vector":{"assistant":0.16436616258133754,"ship":0.038572673909756,"built":0.05654184430554052,"cli":0.06414598442473332,"call":0.03207299221236666,"answer":0.22616737722216207,"question":0.0695412077003192,"framework":0.06414598442473332,"direct":0.0536508844043433,"terminal":0.03207299221236666,"local":0.1390824154006384,"idf":0.0695412077003192,"knowledge":0.20986393446306298,"base":0.09839405154583054,"project":0.02998056206615185,"documentate":0.14135461076385128,"optional":0.02998056206615185,"routes":0.02258715123211851,"through":0.038572673909756,"ollama":0.20986393446306298,"language":0.038572673909756,"model":0.15283078804235847,"richer":0.038572673909756,"more":0.06414598442473332,"conversational":0.0695412077003192,"responses":0.0347706038501596,"external":0.038572673909756,"api":0.02998056206615185,"key":0.02557331051497732,"internet":0.0347706038501596,"connecte":0.038572673909756,"requir":0.02682544220217165,"default":0.060977281514346914,"mode":0.26825442202171645,"building":0.0347706038501596,"before":0.04696176073752502,"first":0.02348088036876251,"time":0.05654184430554052,"generate":0.09839405154583054,"readme":0.06414598442473332,"code":0.26797308854663415,"gen":0.05114662102995464,"parses":0.0347706038501596,"computes":0.0347706038501596,"vector":0.0347706038501596,"writes":0.0347706038501596,"bee_knowledge":0.06414598442473332,"json":0.04354248091076184,"file":0.04354248091076184,"lib":0.0347706038501596,"command":0.06776145369635553,"any":0.02177124045538092,"updat":0.02557331051497732,"interactive":0.18777809541520155,"start":0.037010296378222944,"session":0.0695412077003192,"ask":0.0695412077003192,"domestic":0.0347706038501596,"anything":0.0347706038501596,"type":0.040651521009564616,"exit":0.09621897663709997,"leave":0.0695412077003192,"retrain":0.0347706038501596,"server":0.01967881030916611,"quit":0.0347706038501596,"bye":0.0347706038501596,"single":0.15343986308986388,"shot":0.1798833723969111,"pas":0.02998056206615185,"queste":0.0347706038501596,"line":0.02998056206615185,"argument":0.03207299221236666,"one":0.04517430246423702,"hook":0.0536508844043433,"work":0.06414598442473332,"databases":0.02998056206615185,"support":0.021020675298851113,"jwt":0.02998056206615185,"authenticat":0.02827092215277026,"llm":0.5096695551245815,"install":0.02348088036876251,"running":0.02557331051497732,"enable":0.0347706038501596,"detail":0.0347706038501596,"retrieves":0.0347706038501596,"most":0.0347706038501596,"relevant":0.0347706038501596,"passes":0.0347706038501596,"context":0.0347706038501596,"qwen2":0.09621897663709997,"llama3":0.0347706038501596,"specific":0.09034860492847405,"configure":0.024468852093173864,"websocket":0.02998056206615185,"specifi":0.0347706038501596,"not":0.024468852093173864,"available":0.024468852093173864,"automatical":0.03207299221236666,"pull":0.0347706038501596,"answering":0.0347706038501596,"displaying":0.0347706038501596,"live":0.0347706038501596,"download":0.0347706038501596,"progres":0.0347706038501596,"bar":0.0347706038501596,"environment":0.024468852093173864,"option":0.02348088036876251,"ollama_url":0.0347706038501596,"url":0.02258715123211851,"http":0.042041350597702226,"remote":0.0347706038501596,"host":0.03207299221236666,"11434":0.0347706038501596,"custom":0.08481276645831076,"endpoint":0.02998056206615185,"path":0.02827092215277026,"bee_debug":0.0347706038501596,"debug":0.09621897663709997,"write":0.02827092215277026,"output":0.02827092215277026,"tmp":0.0347706038501596,"bee_ollama_debug":0.0347706038501596,"txt":0.0347706038501596,"suggestion":0.0347706038501596,"after":0.02557331051497732,"every":0.02827092215277026,"suggest":0.0347706038501596,"five":0.0347706038501596,"relat":0.02998056206615185,"topic":0.0347706038501596,"want":0.05654184430554052,"explore":0.03207299221236666,"next":0.02998056206615185,"along":0.0347706038501596,"link":0.0347706038501596,"full":0.02348088036876251,"dedyn":0.02998056206615185,"reference":0.0347706038501596,"build":0.02827092215277026,"alias":0.03207299221236666,"contributing":0.10431181155047879,"interest":0.0347706038501596,"read":0.03207299221236666,"guide":0.0347706038501596,"feel":0.02998056206615185,"free":0.02998056206615185,"open":0.05654184430554052,"issue":0.02998056206615185,"spot":0.0347706038501596,"idea":0.03207299221236666,"discus":0.0347706038501596,"something":0.03207299221236666,"discussion":0.0347706038501596}},{"label":"Bee assistant — Building the knowledge base","body":"Before using the assistant for the first time, generate the knowledge base from the README:\n\nCODE>rubee bee generate # or: rubee bee gen\n\nThis parses the documentation, computes TF-IDF vectors, and writes a bee_knowledge.json file to lib/rubee/cli/. Re-run this command any time the documentation is updated.","parent":"Bee assistant","vector":{"assistant":0.24822266451896136,"building":0.18378467500098117,"knowledge":0.4753988063669338,"base":0.20802996535013876,"before":0.12411133225948068,"first":0.12411133225948068,"time":0.29885947694296783,"generate":0.20802996535013876,"readme":0.16952608805589525,"code":0.056656303353013235,"gen":0.13517115152639797,"parses":0.18378467500098117,"documentate":0.29885947694296783,"computes":0.18378467500098117,"idf":0.18378467500098117,"vector":0.18378467500098117,"writes":0.18378467500098117,"bee_knowledge":0.16952608805589525,"json":0.11507480194198667,"file":0.11507480194198667,"lib":0.18378467500098117,"cli":0.16952608805589525,"command":0.11938740742846943,"any":0.11507480194198667,"updat":0.13517115152639797}},{"label":"Bee assistant — Interactive mode","body":"Start an interactive session and ask questions conversationally:\n\nCODE>rubee bee\n\nCODE> ⬡ ⬢ ⬢ ru.Bee — domestic AI assistant\nCODE> ──────────────────────────────────────────────\nCODE> Ask me anything about the ru.Bee framework.\nCODE> Type exit to leave • rubee bee generate to retrain.\nCODE> You: How do I run the server?\n\nType exit, quit, bye, or q to leave the session.","parent":"Bee assistant","vector":{"assistant":0.23242858849998968,"interactive":0.26553517453431874,"mode":0.13276758726715937,"start":0.09158782392376283,"session":0.34418140407274794,"ask":0.34418140407274794,"question":0.17209070203637397,"conversational":0.17209070203637397,"code":0.31830803146411735,"domestic":0.17209070203637397,"anything":0.17209070203637397,"framework":0.15873936990047408,"type":0.2011972187635812,"exit":0.31747873980094815,"leave":0.34418140407274794,"generate":0.09739664850052596,"retrain":0.17209070203637397,"server":0.09739664850052596,"quit":0.17209070203637397,"bye":0.17209070203637397}},{"label":"Bee assistant — Single-shot mode","body":"Pass a question directly as a command-line argument to get one answer and exit:\n\nCODE>rubee bee how do hooks work\nCODE>rubee bee what databases are supported\nCODE>rubee bee how do I set up JWT authentication","parent":"Bee assistant","vector":{"assistant":0.1842097771558523,"single":0.20062509399640782,"shot":0.23520040860819263,"mode":0.21044818816687588,"pas":0.23520040860819263,"queste":0.27277874961337667,"direct":0.21044818816687588,"command":0.1771983856529212,"line":0.23520040860819263,"argument":0.25161572544874816,"one":0.1771983856529212,"answer":0.2217881181610363,"exit":0.25161572544874816,"code":0.2522729752021261,"hook":0.21044818816687588,"work":0.25161572544874816,"databases":0.23520040860819263,"support":0.16490923047409425,"jwt":0.23520040860819263,"authenticat":0.2217881181610363}},{"label":"Bee assistant — LLM mode","body":"If you have Ollama installed and running locally, enable LLM mode for more detailed answers. The assistant retrieves the most relevant documentation and passes it as context to the model.\n\nCODE>rubee bee --llm # interactive mode, default model (qwen2.5:1.5b)\nCODE>rubee bee --llm=llama3.2 # interactive mode, specific model\nCODE>rubee bee --llm how do hooks work # single-shot LLM answer\nCODE>rubee bee --llm=qwen2.5:0.5b how do I configure WebSocket # single-shot with specific model\n\nIf the specified model is not available locally, the assistant automatically pulls it from Ollama before answering, displaying a live download progress bar.","parent":"Bee assistant","vector":{"assistant":0.19904042926799895,"llm":0.5929846886401147,"mode":0.30318837836689594,"ollama":0.16942419675431847,"install":0.06634680975599964,"running":0.0722591121338661,"local":0.19649336843577192,"enable":0.09824668421788596,"more":0.09062440075502569,"detail":0.09824668421788596,"answer":0.15976279119345274,"retrieves":0.09824668421788596,"most":0.09824668421788596,"relevant":0.09824668421788596,"documentate":0.07988139559672637,"passes":0.09824668421788596,"context":0.09824668421788596,"model":0.23990760567420027,"code":0.12114816307608951,"interactive":0.15159418918344797,"default":0.0574318059705644,"qwen2":0.18124880151005138,"llama3":0.09824668421788596,"specific":0.1276430357118112,"hook":0.07579709459172398,"work":0.09062440075502569,"single":0.1445182242677322,"shot":0.16942419675431847,"configure":0.06913839043842708,"websocket":0.08471209837715923,"specifi":0.09824668421788596,"not":0.06913839043842708,"available":0.06913839043842708,"automatical":0.09062440075502569,"pull":0.09824668421788596,"before":0.06634680975599964,"answering":0.09824668421788596,"displaying":0.09824668421788596,"live":0.09824668421788596,"download":0.09824668421788596,"progres":0.09824668421788596,"bar":0.09824668421788596}},{"label":"Bee assistant — Environment options","body":"CODE>OLLAMA_URL=http://remote-host:11434 rubee bee --llm # use a custom Ollama endpoint\nCODE>BEE_KNOWLEDGE=/path/to/custom.json rubee bee # use a custom knowledge base file\nCODE>BEE_DEBUG=1 rubee bee --llm # write LLM debug output to /tmp/bee_ollama_debug.txt","parent":"Bee assistant","vector":{"assistant":0.10006342856753579,"environment":0.1042736556339748,"option":0.10006342856753579,"code":0.1370356081170456,"ollama_url":0.1481744202078184,"ollama":0.38328518142512846,"url":0.09625481491170909,"http":0.08957930061285882,"remote":0.1481744202078184,"host":0.13667858763331459,"11434":0.1481744202078184,"llm":0.38328518142512846,"custom":0.36142836490093405,"endpoint":0.1277617271417095,"bee_knowledge":0.13667858763331459,"knowledge":0.255523454283419,"path":0.1204761216336447,"json":0.09277782305947098,"base":0.0838609625678659,"file":0.09277782305947098,"bee_debug":0.1481744202078184,"debug":0.41003576289994376,"write":0.1204761216336447,"output":0.1204761216336447,"tmp":0.1481744202078184,"bee_ollama_debug":0.1481744202078184,"txt":0.1481744202078184}},{"label":"Bee assistant — Suggestions","body":"After every answer, the assistant suggests up to five related topics you might want to explore next, along with a link to the full documentation at https://rubee.dedyn.io/.","parent":"Bee assistant","vector":{"assistant":0.34975308908518193,"suggestion":0.25895805257218635,"after":0.1904601575894675,"every":0.21055092907360207,"answer":0.21055092907360207,"suggest":0.25895805257218635,"five":0.25895805257218635,"relat":0.22328366804117528,"topic":0.25895805257218635,"want":0.21055092907360207,"explore":0.2388672810880518,"next":0.22328366804117528,"along":0.25895805257218635,"link":0.25895805257218635,"full":0.17487654454259097,"documentate":0.21055092907360207,"http":0.15655388565009806,"dedyn":0.22328366804117528}},{"label":"Bee assistant — Command reference","body":"CODE>rubee bee generate # build the knowledge base from the README\nCODE>rubee bee gen # alias for generate\nCODE>rubee bee # start interactive mode\nCODE>rubee bee # single-shot answer\nCODE>rubee bee --llm # interactive LLM mode (default model: qwen2.5:1.5b)\nCODE>rubee bee --llm= # interactive LLM mode with a specific Ollama model\nCODE>rubee bee --llm # single-shot LLM answer\nCODE>rubee bee --llm= # single-shot with a specific model","parent":"Bee assistant","vector":{"assistant":0.07521567653622983,"command":0.07235281787858568,"reference":0.11137974603551137,"code":0.27468513046523885,"generate":0.12607321425658033,"build":0.0905594893644854,"knowledge":0.0960359332072558,"base":0.06303660712829016,"readme":0.10273855877242508,"gen":0.08191830210139912,"alias":0.10273855877242508,"start":0.0592770466263639,"interactive":0.2577876662117088,"mode":0.2577876662117088,"single":0.24575490630419736,"shot":0.2881077996217674,"answer":0.1811189787289708,"llm":0.6722515324507906,"default":0.06510896539954364,"model":0.16318625959561162,"qwen2":0.10273855877242508,"specific":0.14470563575717135,"ollama":0.0960359332072558}},{"label":"Bee assistant — Contributing","body":"If you are interested in contributing to ru.Bee, please read the Contributing guide.\nFeel free to open an issue if you spot one.\nHave an idea or want to discuss something? Open a discussion.","parent":"Bee assistant","vector":{"assistant":0.14091460716604184,"contributing":0.6260011429115158,"interest":0.20866704763717195,"read":0.1924780087997764,"guide":0.20866704763717195,"feel":0.17992081471481788,"free":0.17992081471481788,"open":0.3393216801767918,"issue":0.17992081471481788,"spot":0.20866704763717195,"one":0.1355511161799638,"idea":0.1924780087997764,"want":0.1696608400883959,"discus":0.20866704763717195,"something":0.1924780087997764,"discussion":0.20866704763717195}}]}
|
|
1
|
+
{"version":"0.1.0","idf":{"producte":2.890850371872286,"ready":3.3608540011180215,"take":4.277144732992177,"look":4.277144732992177,"demo":3.8716796248840124,"site":3.3608540011180215,"full":2.667706820558076,"documentate":2.890850371872286,"http":2.197703191312341,"dedyn":3.3608540011180215,"want":3.178532444324067,"explore":3.583997552432231,"built":3.178532444324067,"github":3.583997552432231,"com":2.4853852637641216,"nucleom42":4.277144732992177,"stres":4.277144732992177,"test":2.197703191312341,"code":1.1636294237818021,"wrk":4.277144732992177,"c100":4.277144732992177,"d30":4.277144732992177,"doc":4.277144732992177,"running":2.5723966407537513,"30":4.277144732992177,"thread":4.277144732992177,"100":3.583997552432231,"connection":3.583997552432231,"stat":4.277144732992177,"avg":4.277144732992177,"stdev":4.277144732992177,"max":3.3608540011180215,"latency":4.277144732992177,"304":4.277144732992177,"95m":4.277144732992177,"22m":4.277144732992177,"551":4.277144732992177,"86m":4.277144732992177,"req":4.277144732992177,"sec":4.277144732992177,"280":4.277144732992177,"9721":4.277144732992177,"request":3.8716796248840124,"02":4.277144732992177,"11mb":4.277144732992177,"read":3.178532444324067,"323":4.277144732992177,"transfer":4.277144732992177,"140":4.277144732992177,"07kb":4.277144732992177,"short":3.8716796248840124,"output":3.178532444324067,"explanate":4.277144732992177,"324":4.277144732992177,"average":4.277144732992177,"305":4.277144732992177,"total":3.583997552432231,"handl":4.277144732992177,"721":4.277144732992177,"hardware":4.277144732992177,"raspberry":4.277144732992177,"single":2.890850371872286,"board":4.277144732992177,"computer":4.277144732992177,"server":2.331234583936863,"app":2.137078569495906,"host":3.583997552432231,"nginx":4.277144732992177,"demonstrates":4.277144732992177,"efficient":3.8716796248840124,"architecture":4.277144732992177,"suitability":4.277144732992177,"lightweight":3.8716796248840124,"deployment":4.277144732992177,"even":4.277144732992177,"low":3.3608540011180215,"power":3.8716796248840124,"comparison":4.277144732992177,"here":3.8716796248840124,"web":3.178532444324067,"framework":3.178532444324067,"ruby":2.4853852637641216,"evaluate":4.277144732992177,"choice":4.277144732992177,"disclaimer":4.277144732992177,"bas":3.178532444324067,"generic":4.277144732992177,"subjective":4.277144732992177,"informate":4.277144732992177,"available":2.7730673362159024,"internet":3.8716796248840124,"not":2.4853852637641216,"real":4.277144732992177,"benchmark":4.277144732992177,"aim":4.277144732992177,"giving":4.277144732992177,"general":4.277144732992177,"idea":3.583997552432231,"differences":4.277144732992177,"between":4.277144732992177,"intend":4.277144732992177,"direct":3.0243817644968085,"features":4.277144732992177,"minimal":4.277144732992177,"footprint":4.277144732992177,"focus":4.277144732992177,"serving":4.277144732992177,"applicate":3.583997552432231,"modular":3.583997552432231,"approach":4.277144732992177,"applicat":2.7730673362159024,"development":2.4053425560905852,"build":2.890850371872286,"monolith":4.277144732992177,"ease":3.8716796248840124,"attaching":4.277144732992177,"many":3.178532444324067,"subproject":3.583997552432231,"ne":3.0243817644968085,"contract":3.8716796248840124,"driven":4.277144732992177,"define":3.178532444324067,"api":3.3608540011180215,"simple":3.3608540011180215,"declarative":4.277144732992177,"way":3.8716796248840124,"then":2.890850371872286,"generate":2.137078569495906,"all":2.331234583936863,"boilerplate":4.277144732992177,"fast":4.277144732992177,"optimiz":4.277144732992177,"spe":3.8716796248840124,"providing":4.277144732992177,"quick":4.277144732992177,"responses":3.8716796248840124,"rack":2.7730673362159024,"easy":4.277144732992177,"integrate":3.583997552432231,"databases":3.3608540011180215,"support":2.262241712449912,"sqlite3":3.8716796248840124,"postgresql":3.8716796248840124,"mysql":4.277144732992177,"more":3.0243817644968085,"sequel":3.0243817644968085,"gem":2.890850371872286,"view":2.197703191312341,"json":2.262241712449912,"erb":2.890850371872286,"plain":3.8716796248840124,"html":3.8716796248840124,"box":3.583997552432231,"react":3.0243817644968085,"first":2.4853852637641216,"clas":1.925769475828699,"engine":2.667706820558076,"bundlable":4.277144732992177,"charge":4.277144732992177,"any":2.4853852637641216,"update":2.667706820558076,"effortles":4.277144732992177,"bundler":3.8716796248840124,"orm":3.583997552432231,"agnostic":4.277144732992177,"model":1.9745596399981307,"native":4.277144732992177,"object":2.4053425560905852,"but":4.277144732992177,"them":3.583997552432231,"blueprint":4.277144732992177,"data":2.890850371872286,"source":4.277144732992177,"authenticatable":4.277144732992177,"easi":4.277144732992177,"add":2.4053425560905852,"jwt":3.3608540011180215,"authenticat":2.7730673362159024,"controller":2.4053425560905852,"acte":3.0243817644968085,"hook":3.0243817644968085,"logic":3.178532444324067,"before":2.5723966407537513,"after":2.890850371872286,"around":3.8716796248840124,"testable":4.277144732992177,"select":4.277144732992177,"belov":4.277144732992177,"minitest":4.277144732992177,"asyncable":3.3608540011180215,"plug":3.8716796248840124,"async":3.3608540011180215,"adapter":3.583997552432231,"popular":4.277144732992177,"background":3.3608540011180215,"job":3.178532444324067,"console":3.8716796248840124,"start":2.0258529343856813,"interactive":3.0243817644968085,"reload":3.3608540011180215,"f":4.277144732992177,"schedule":3.8716796248840124,"proces":3.3608540011180215,"preferr":4.277144732992177,"stack":3.8716796248840124,"websocket":3.3608540011180215,"serve":4.277144732992177,"handle":3.583997552432231,"logger":3.583997552432231,"installate":4.277144732992177,"install":2.667706820558076,"create":2.137078569495906,"project":3.3608540011180215,"my_project":4.277144732992177,"dependency":3.178532444324067,"prerequisites":3.583997552432231,"higher":3.583997552432231,"recommend":3.583997552432231,"bundle":3.583997552432231,"default":2.262241712449912,"port":3.583997552432231,"7000":3.583997552432231,"start_dev":3.0243817644968085,"dev":2.890850371872286,"starting":3.0243817644968085,"version":2.890850371872286,"yjit":4.277144732992177,"compiler":4.277144732992177,"boost":4.277144732992177,"jit":4.277144732992177,"opte":4.277144732992177,"environment":2.667706820558076,"too":4.277144732992177,"open":3.178532444324067,"browser":3.583997552432231,"localhost":2.890850371872286,"specify":4.277144732992177,"specific":2.5723966407537513,"file":2.4853852637641216,"user_model_test":3.8716796248840124,"user":2.137078569495906,"line":3.3608540011180215,"draw":2.7730673362159024,"routes":2.4853852637641216,"router":2.667706820558076,"apples":2.7730673362159024,"index":2.5723966407537513,"name":2.262241712449912,"apple":3.178532444324067,"attributes":2.890850371872286,"type":2.331234583936863,"primary":3.178532444324067,"colour":3.178532444324067,"string":2.5723966407537513,"weight":2.890850371872286,"integer":3.178532444324067,"creat":3.0243817644968085,"datetime":3.178532444324067,"updat":2.890850371872286,"end":1.879249460193806,"files":3.178532444324067,"apples_controller":3.583997552432231,"respective":4.277144732992177,"apples_index":3.583997552432231,"render":3.0243817644968085,"act":4.277144732992177,"create_apples":3.3608540011180215,"database":2.4053425560905852,"migrate":2.890850371872286,"table":3.583997552432231,"initial":3.583997552432231,"fill":3.583997552432231,"generat":2.890850371872286,"again":4.277144732992177,"find":3.0243817644968085,"snapshot":4.277144732992177,"schema":3.583997552432231,"structure":3.3608540011180215,"constant":4.277144732992177,"print":3.583997552432231,"latest":3.8716796248840124,"cli":3.178532444324067,"email":2.4853852637641216,"varchar":4.277144732992177,"255":4.277144732992177,"password":2.4853852637641216,"account":3.8716796248840124,"addres":4.277144732992177,"user_id":3.583997552432231,"post":2.890850371872286,"comment_id":3.583997552432231,"comment":3.583997552432231,"text":3.178532444324067,"nullable":4.277144732992177,"foreign":3.583997552432231,"key":2.667706820558076,"delete":3.583997552432231,"no_acte":4.277144732992177,"dropping":4.277144732992177,"tables":4.277144732992177,"handy":4.277144732992177,"during":4.277144732992177,"careful":4.277144732992177,"pas":2.890850371872286,"desir":3.8716796248840124,"rack_env":3.583997552432231,"env":2.4053425560905852,"drop_tables":4.277144732992177,"drop":4.277144732992177,"dropp":4.277144732992177,"company":4.277144732992177,"company_client":4.277144732992177,"client":3.0243817644968085,"services":3.8716796248840124,"serializ":4.277144732992177,"whatever":4.277144732992177,"form":4.277144732992177,"requir":2.7730673362159024,"rendering":4.277144732992177,"memory":3.8716796248840124,"applescontroller":3.8716796248840124,"def":2.262241712449912,"new":2.4853852637641216,"r":4.277144732992177,"1lb":4.277144732992177,"green":4.277144732992177,"param":3.583997552432231,"response_with":2.7730673362159024,"response":2.5723966407537513,"serializable":4.277144732992177,"module":3.3608540011180215,"includ":4.277144732992177,"target":3.8716796248840124,"include":2.331234583936863,"attr_accessor":3.8716796248840124,"attr":3.8716796248840124,"accessor":3.8716796248840124,"turn":4.277144732992177,"extending":4.277144732992177,"sequelobject":3.583997552432231,"already":4.277144732992177,"charg":3.583997552432231,"llo":3.8716796248840124,"543":3.8716796248840124,"save":3.583997552432231,"record":3.3608540011180215,"irb":3.583997552432231,"main":2.667706820558076,"018":3.8716796248840124,"true":2.4853852637641216,"value":3.583997552432231,"019":3.8716796248840124,"check":3.3608540011180215,"whether":3.8716796248840124,"persist":3.583997552432231,"016":3.8716796248840124,"false":3.0243817644968085,"011":3.8716796248840124,"last":2.890850371872286,"012":3.8716796248840124,"014":3.8716796248840124,"unpersist":3.8716796248840124,"refresh":3.8716796248840124,"assign":3.8716796248840124,"without":3.3608540011180215,"persisting":3.8716796248840124,"008":3.8716796248840124,"assign_attributes":3.8716796248840124,"ok23":3.8716796248840124,"123":3.0243817644968085,"scop":3.8716796248840124,"field":3.583997552432231,"005":3.8716796248840124,"001":3.8716796248840124,"002":3.8716796248840124,"003":3.8716796248840124,"004":3.8716796248840124,"destroy":3.8716796248840124,"relat":3.3608540011180215,"021":3.8716796248840124,"cascade":3.8716796248840124,"initialize":2.890850371872286,"instance":3.8716796248840124,"subsequent":3.8716796248840124,"persistence":3.583997552432231,"020":3.8716796248840124,"find_or_new":3.8716796248840124,"022":3.8716796248840124,"023":3.8716796248840124,"one":2.4053425560905852,"destroy_all":3.8716796248840124,"complex":3.8716796248840124,"query":3.8716796248840124,"chain":3.8716796248840124,"serialize":3.8716796248840124,"result":3.3608540011180215,"back":3.8716796248840124,"dataset":3.583997552432231,"join":3.583997552432231,"009":3.8716796248840124,"010":3.8716796248840124,"since":3.8716796248840124,"method":2.4853852637641216,"order":3.8716796248840124,"limit":3.8716796248840124,"offset":3.8716796248840124,"owns_many":3.8716796248840124,"own":3.178532444324067,"owns_one":3.8716796248840124,"paginate":3.8716796248840124,"page":3.8716796248840124,"per_page":3.8716796248840124,"per":3.8716796248840124,"pagination_meta":3.8716796248840124,"meta":3.8716796248840124,"current_page":3.8716796248840124,"current":3.3608540011180215,"total_count":3.8716796248840124,"count":3.8716796248840124,"first_page":3.8716796248840124,"last_page":3.8716796248840124,"prev":3.8716796248840124,"nil":3.8716796248840124,"next":3.3608540011180215,"base":2.262241712449912,"initiate":4.277144732992177,"015":4.277144732992177,"postgres":4.277144732992177,"sqlite":3.0243817644968085,"ful":4.277144732992177,"potential":4.277144732992177,"us":3.583997552432231,"gemfile":3.3608540011180215,"url":2.5723966407537513,"each":3.178532444324067,"config":2.331234583936863,"base_configurate":2.7730673362159024,"configurate":2.5723966407537513,"setup":2.667706820558076,"database_url":3.178532444324067,"configure":2.7730673362159024,"5432":4.277144732992177,"db_password":4.277144732992177,"suite":4.277144732992177,"ensure":3.583997552432231,"initializ":4.277144732992177,"init":2.890850371872286,"ensures":4.277144732992177,"run":4.277144732992177,"issue":3.3608540011180215,"write":2.890850371872286,"locking":3.8716796248840124,"resolv":3.8716796248840124,"tune":3.8716796248840124,"retry":2.890850371872286,"parameter":3.583997552432231,"need":3.0243817644968085,"db_max_retry":4.277144732992177,"disable":4.277144732992177,"increase":4.277144732992177,"db_retry_delay":4.277144732992177,"delay":4.277144732992177,"db_busy_timeout":4.277144732992177,"busy":4.277144732992177,"timeout":4.277144732992177,"1000":4.277144732992177,"millisecond":4.277144732992177,"raising":4.277144732992177,"error":2.667706820558076,"automatical":3.583997552432231,"dbtool":4.277144732992177,"with_retry":4.277144732992177,"insert":4.277144732992177,"routing":3.178532444324067,"uses":4.277144732992177,"explicit":3.8716796248840124,"match":3.3608540011180215,"denot":4.277144732992177,"route":2.7730673362159024,"path":2.890850371872286,"a_key":4.277144732992177,"somewhere":4.277144732992177,"patch":3.583997552432231,"put":3.178532444324067,"head":3.8716796248840124,"connect":3.8716796248840124,"option":2.5723966407537513,"trace":3.8716796248840124,"every":3.178532444324067,"follow":3.8716796248840124,"http_method":3.8716796248840124,"optional":3.178532444324067,"namespace":3.583997552432231,"defining":3.8716796248840124,"unique":3.8716796248840124,"trait":3.8716796248840124,"other":3.8716796248840124,"attribute":3.583997552432231,"types":3.8716796248840124,"descripte":3.8716796248840124,"quantity":3.8716796248840124,"date":3.8716796248840124,"modifi":3.8716796248840124,"exist":3.3608540011180215,"time":2.890850371872286,"active":3.8716796248840124,"boolean":3.8716796248840124,"hash":3.583997552432231,"bigint":3.8716796248840124,"price":3.8716796248840124,"decimal":3.8716796248840124,"item_id":3.8716796248840124,"item":3.8716796248840124,"foreign_key":3.8716796248840124,"item_id_index":3.8716796248840124,"item_id_unique":3.8716796248840124,"carry":3.8716796248840124,"definite":3.8716796248840124,"size":3.8716796248840124,"fix":3.8716796248840124,"get":3.583997552432231,"translat":3.8716796248840124,"long":3.8716796248840124,"on":3.583997552432231,"defin":3.583997552432231,"gen":2.890850371872286,"generates":3.583997552432231,"attach":3.8716796248840124,"folder":3.8716796248840124,"mvc":3.8716796248840124,"namespacing":3.8716796248840124,"while":3.8716796248840124,"still":3.8716796248840124,"sharing":3.8716796248840124,"admin":3.3608540011180215,"admin_routes":3.8716796248840124,"cabbages":3.8716796248840124,"cabbage":3.8716796248840124,"mandatory":3.583997552432231,"command":2.4853852637641216,"cabbages_controller":3.8716796248840124,"cabbages_index":3.8716796248840124,"create_cabbages":3.8716796248840124,"content":3.8716796248840124,"cabbagescontroller":3.8716796248840124,"basecontroller":3.178532444324067,"templates":3.8716796248840124,"layout":3.8716796248840124,"parent":3.8716796248840124,"template":3.8716796248840124,"child":3.8716796248840124,"inside":3.583997552432231,"feel":3.3608540011180215,"free":3.3608540011180215,"custom":3.178532444324067,"cs":3.8716796248840124,"there":3.583997552432231,"welcome_controller":3.583997552432231,"welcome":3.0243817644968085,"welcomecontroller":3.583997552432231,"layer":3.8716796248840124,"node":3.8716796248840124,"npm":3.8716796248840124,"creating":3.8716796248840124,"bundling":3.8716796248840124,"prepare":3.583997552432231,"register":3.583997552432231,"change":3.8716796248840124,"3000":3.8716796248840124,"navigate":3.8716796248840124,"home":3.8716796248840124,"terminal":3.583997552432231,"watch":3.178532444324067,"another":3.8716796248840124,"changes":3.3608540011180215,"instant":3.8716796248840124,"rebuild":3.8716796248840124,"specifying":3.8716796248840124,"view_name":3.8716796248840124,"tsx":3.8716796248840124,"backend":3.8716796248840124,"endpoint":3.3608540011180215,"shown":3.8716796248840124,"below":3.8716796248840124,"user_controller":3.8716796248840124,"usercontroller":3.8716796248840124,"fetch":3.178532444324067,"component":3.8716796248840124,"import":3.8716796248840124,"usestate":3.8716796248840124,"useeffect":3.8716796248840124,"functe":3.8716796248840124,"const":3.3608540011180215,"setuser":3.8716796248840124,"return":3.3608540011180215,"map":3.8716796248840124,"including":3.8716796248840124,"hookable":4.277144732992177,"executes":4.277144732992177,"call":3.0243817644968085,"lambda":4.277144732992177,"index2":4.277144732992177,"unles":3.178532444324067,"guard":3.8716796248840124,"accept":4.277144732992177,"log":3.3608540011180215,"print_hello":4.277144732992177,"hello":3.3608540011180215,"res":4.277144732992177,"yield":4.277144732992177,"execute":3.8716796248840124,"127":3.8716796248840124,"feb":4.277144732992177,"2025":3.8716796248840124,"0500":4.277144732992177,"401":4.277144732992177,"0359":4.277144732992177,"pinn":4.277144732992177,"anyclas":4.277144732992177,"print_world":4.277144732992177,"world":4.277144732992177,"class_method":4.277144732992177,"self":4.277144732992177,"validate":4.277144732992177,"validatable":4.277144732992177,"foo":4.277144732992177,"age":3.583997552432231,"condite":4.277144732992177,"length":4.277144732992177,"error_message":4.277144732992177,"message":3.583997552432231,"must":3.8716796248840124,"fancy_error":4.277144732992177,"fancy":4.277144732992177,"least":3.583997552432231,"year":4.277144732992177,"old":4.277144732992177,"041":4.277144732992177,"valid":4.277144732992177,"042":4.277144732992177,"046":4.277144732992177,"joe":4.277144732992177,"wrong":3.583997552432231,"047":4.277144732992177,"format":4.277144732992177,"077":4.277144732992177,"078":4.277144732992177,"080":4.277144732992177,"validate_before_persist":4.277144732992177,"validate_after_setter":4.277144732992177,"setter":4.277144732992177,"global":3.8716796248840124,"initializer":4.277144732992177,"such":4.277144732992177,"sequel_object_preloader":4.277144732992177,"preloader":4.277144732992177,"useful":4.277144732992177,"classes":4.277144732992177,"rubee_support":4.277144732992177,"extension":4.277144732992177,"tolerates":4.277144732992177,"symbol":4.277144732992177,"interchangeab":4.277144732992177,"deep":4.277144732992177,"digging":4.277144732992177,"two":3.8716796248840124,"deep_dig":4.277144732992177,"dig":4.277144732992177,"enrich":4.277144732992177,"helper":3.583997552432231,"pluralize":4.277144732992177,"singularize":4.277144732992177,"camelize":4.277144732992177,"testme":4.277144732992177,"snakeize":4.277144732992177,"test_me":4.277144732992177,"singular":4.277144732992177,"plural":4.277144732992177,"authtokenable":3.8716796248840124,"authenticate":3.8716796248840124,"create_user":4.277144732992177,"creates":4.277144732992177,"seed":4.277144732992177,"credential":3.583997552432231,"customize":4.277144732992177,"userscontroller":3.8716796248840124,"auth_method":4.277144732992177,"auth":3.178532444324067,"unauthenticat":4.277144732992177,"action":4.277144732992177,"reject":4.277144732992177,"login":3.3608540011180215,"edit":3.8716796248840124,"initializes":4.277144732992177,"token_header":3.8716796248840124,"token":3.8716796248840124,"header":3.8716796248840124,"redirect":3.8716796248840124,"else":3.178532444324067,"render_view":3.8716796248840124,"users_edit":3.8716796248840124,"logout":3.8716796248840124,"unauthenticate":3.8716796248840124,"zeroed_token_header":3.8716796248840124,"zero":3.8716796248840124,"restrict":4.277144732992177,"jwt_key":4.277144732992177,"startup":4.277144732992177,"security":4.277144732992177,"sdjwer0wer23j":4.277144732992177,"instead":3.583997552432231,"argument":3.178532444324067,"user_model":4.277144732992177,"digest_password":4.277144732992177,"digest":4.277144732992177,"oauth":4.277144732992177,"oauth2":4.277144732992177,"point":4.277144732992177,"redirect_uri":4.277144732992177,"uri":4.277144732992177,"mysite":4.277144732992177,"oauth_callback":4.277144732992177,"callback":4.277144732992177,"client_id":4.277144732992177,"google_client_id":4.277144732992177,"google":4.277144732992177,"client_secret":4.277144732992177,"secret":3.3608540011180215,"google_client_secret":4.277144732992177,"section":4.277144732992177,"oauth_login":4.277144732992177,"auth_client":4.277144732992177,"auth_code":4.277144732992177,"authorize_url":4.277144732992177,"authorize":4.277144732992177,"scope":4.277144732992177,"profile":4.277144732992177,"openid":4.277144732992177,"get_token":4.277144732992177,"user_info":4.277144732992177,"info":3.0243817644968085,"parse":3.3608540011180215,"www":4.277144732992177,"googleapis":4.277144732992177,"userinfo":4.277144732992177,"alt":4.277144732992177,"body":3.583997552432231,"raise":4.277144732992177,"found":4.277144732992177,"something":3.583997552432231,"went":4.277144732992177,"rescue":3.3608540011180215,"fail":3.3608540011180215,"standarderror":3.8716796248840124,"private":3.3608540011180215,"token_url":4.277144732992177,"mode":2.7730673362159024,"restarting":4.277144732992177,"together":4.277144732992177,"stop":3.583997552432231,"restart":4.277144732992177,"shorthand":4.277144732992177,"alias":3.583997552432231,"pick":4.277144732992177,"prefix":4.277144732992177,"variable":4.277144732992177,"testing":4.277144732992177,"auth_tokenable_test":4.277144732992177,"tokenable":4.277144732992177,"sidekiq":2.667706820558076,"threadasync":3.583997552432231,"allow":4.277144732992177,"redis":3.3608540011180215,"session":3.178532444324067,"async_adapter":4.277144732992177,"sidekiqasync":4.277144732992177,"macos":3.8716796248840124,"homebrew":4.277144732992177,"brew":3.8716796248840124,"verify":3.8716796248840124,"ping":3.8716796248840124,"respond":4.277144732992177,"pong":4.277144732992177,"yml":3.583997552432231,"concurrency":4.277144732992177,"queues":3.583997552432231,"mailer":3.583997552432231,"critical":3.3608540011180215,"connecte":3.583997552432231,"6379":3.583997552432231,"logging":4.277144732992177,"verbose":4.277144732992177,"logfile":4.277144732992177,"pid":3.8716796248840124,"daemon":3.8716796248840124,"pidfile":4.277144732992177,"tmp":3.3608540011180215,"boot":4.277144732992177,"configure_server":4.277144732992177,"redis_url":3.583997552432231,"configure_client":4.277144732992177,"load":3.8716796248840124,"context":3.583997552432231,"const_defin":4.277144732992177,"require":3.583997552432231,"variables":3.583997552432231,"require_relative":3.8716796248840124,"relative":3.8716796248840124,"dir":4.277144732992177,"trigger":4.277144732992177,"autoload":4.277144732992177,"worker":3.3608540011180215,"test_async_runner":3.8716796248840124,"runner":3.8716796248840124,"testasyncrunner":3.8716796248840124,"sidekiq_option":3.8716796248840124,"queue":3.178532444324067,"perform":3.3608540011180215,"parse_option":3.8716796248840124,"is_a":3.8716796248840124,"begin":4.277144732992177,"parsererror":4.277144732992177,"codebase":4.277144732992177,"enqueue":4.277144732992177,"asynchronous":4.277144732992177,"perform_async":3.583997552432231,"to_json":3.8716796248840124,"minutes":4.277144732992177,"300":4.277144732992177,"second":3.8716796248840124,"perform_in":4.277144732992177,"foreground":3.8716796248840124,"exec":3.8716796248840124,"kill":3.8716796248840124,"term":3.8716796248840124,"cat":3.8716796248840124,"tail":3.583997552432231,"script":3.583997552432231,"convenience":3.8716796248840124,"bin":3.8716796248840124,"sidekiq_start":3.8716796248840124,"bash":3.8716796248840124,"echo":3.8716796248840124,"sidekiq_stop":3.8716796248840124,"stopp":3.8716796248840124,"executable":3.8716796248840124,"chmod":3.8716796248840124,"dashboard":3.8716796248840124,"middleware":3.583997552432231,"middlewares":3.583997552432231,"sidekiq_middleware":3.8716796248840124,"sidekiqmiddleware":3.8716796248840124,"session_secret":3.583997552432231,"generate_secret":3.8716796248840124,"sidekiq_app":3.8716796248840124,"builder":3.8716796248840124,"csrf":3.8716796248840124,"protecte":3.8716796248840124,"cookie":3.8716796248840124,"same_site":3.8716796248840124,"same":3.583997552432231,"max_age":3.8716796248840124,"86400":3.8716796248840124,"basic":3.8716796248840124,"username":3.583997552432231,"sidekiq_username":3.583997552432231,"sidekiq_password":3.583997552432231,"path_info":3.8716796248840124,"start_with":3.8716796248840124,"script_name":3.8716796248840124,"sub":3.583997552432231,"through":3.583997552432231,"secret_file":3.8716796248840124,"strip":3.8716796248840124,"securerandom":3.8716796248840124,"hex":3.8716796248840124,"your_secure_password":3.8716796248840124,"secure":3.8716796248840124,"generate_with_securerandom_hex_64":3.8716796248840124,"acces":3.8716796248840124,"visit":3.8716796248840124,"9292":3.8716796248840124,"examples":3.8716796248840124,"email_worker":3.8716796248840124,"emailworker":3.8716796248840124,"send_email":3.8716796248840124,"send":3.8716796248840124,"subject":3.8716796248840124,"usage":3.8716796248840124,"booking_confirmation_worker":3.8716796248840124,"booking":3.583997552432231,"confirmate":3.8716796248840124,"bookingconfirmationworker":3.8716796248840124,"service":3.8716796248840124,"service_id":3.8716796248840124,"time_slot":3.8716796248840124,"slot":3.8716796248840124,"timeslot":3.8716796248840124,"time_slot_id":3.8716796248840124,"booking_confirmate":3.8716796248840124,"client_name":3.8716796248840124,"john":3.8716796248840124,"doe":3.8716796248840124,"priority":3.583997552432231,"processing":3.583997552432231,"mean":3.8716796248840124,"frequent":3.8716796248840124,"monitoring":3.8716796248840124,"troubleshooting":3.8716796248840124,"status":3.583997552432231,"processes":3.8716796248840124,"aux":3.8716796248840124,"grep":3.8716796248840124,"sizes":3.8716796248840124,"llen":3.8716796248840124,"lines":3.8716796248840124,"common":3.8716796248840124,"issues":3.583997552432231,"names":3.583997552432231,"bytes":3.8716796248840124,"failing":3.8716796248840124,"best":3.8716796248840124,"practices":3.8716796248840124,"id":3.8716796248840124,"itself":3.8716796248840124,"avoid":3.8716796248840124,"serializate":3.8716796248840124,"keep":3.8716796248840124,"small":3.8716796248840124,"thing":3.8716796248840124,"well":3.8716796248840124,"idempotent":3.8716796248840124,"safe":3.8716796248840124,"multiple":3.8716796248840124,"times":3.8716796248840124,"appropriate":3.8716796248840124,"fewer":3.8716796248840124,"notificate":3.8716796248840124,"different":3.8716796248840124,"separate":3.8716796248840124,"proper":3.8716796248840124,"alway":3.8716796248840124,"monitor":3.8716796248840124,"backlog":3.8716796248840124,"additional":3.8716796248840124,"resources":3.8716796248840124,"official":3.8716796248840124,"wiki":3.8716796248840124,"guide":3.3608540011180215,"handling":3.8716796248840124,"yet":3.8716796248840124,"caute":3.8716796248840124,"setting":4.277144732992177,"mylogger":4.277144732992177,"level":4.277144732992177,"target_method":4.277144732992177,"now":4.277144732992177,"warn":4.277144732992177,"warning":4.277144732992177,"class_name":4.277144732992177,"fire":4.277144732992177,"debug":3.583997552432231,"000655":4.277144732992177,"sudo":4.277144732992177,"apt":4.277144732992177,"linux":4.277144732992177,"6378":4.277144732992177,"entry":4.277144732992177,"website":4.277144732992177,"pub":4.277144732992177,"capable":4.277144732992177,"system":4.277144732992177,"expect":4.277144732992177,"unsubscribe":4.277144732992177,"channel":4.277144732992177,"subscriber":4.277144732992177,"sender_id":4.277144732992177,"sender":4.277144732992177,"unsub":4.277144732992177,"arg":4.277144732992177,"websocket_connection":4.277144732992177,"remove":4.277144732992177,"merge":4.277144732992177,"unsubscrib":4.277144732992177,"publish":4.277144732992177,"sender_name":4.277144732992177,"stream":4.277144732992177,"chat":4.277144732992177,"see":4.277144732992177,"assistant":2.667706820558076,"ship":4.277144732992177,"answer":3.178532444324067,"question":3.8716796248840124,"local":3.8716796248840124,"idf":3.8716796248840124,"knowledge":3.3608540011180215,"ollama":3.3608540011180215,"language":4.277144732992177,"richer":4.277144732992177,"conversational":3.8716796248840124,"external":4.277144732992177,"building":3.8716796248840124,"readme":3.583997552432231,"parses":3.8716796248840124,"computes":3.8716796248840124,"vector":3.8716796248840124,"writes":3.8716796248840124,"bee_knowledge":3.583997552432231,"lib":3.8716796248840124,"ask":3.8716796248840124,"domestic":3.8716796248840124,"anything":3.8716796248840124,"exit":3.583997552432231,"leave":3.8716796248840124,"retrain":3.8716796248840124,"quit":3.8716796248840124,"bye":3.8716796248840124,"shot":3.3608540011180215,"queste":3.8716796248840124,"work":3.583997552432231,"llm":3.3608540011180215,"enable":3.8716796248840124,"detail":3.8716796248840124,"retrieves":3.8716796248840124,"most":3.8716796248840124,"relevant":3.8716796248840124,"passes":3.8716796248840124,"qwen2":3.583997552432231,"llama3":3.8716796248840124,"specifi":3.8716796248840124,"pull":3.8716796248840124,"answering":3.8716796248840124,"displaying":3.8716796248840124,"live":3.8716796248840124,"download":3.8716796248840124,"progres":3.8716796248840124,"bar":3.8716796248840124,"ollama_url":3.8716796248840124,"remote":3.8716796248840124,"11434":3.8716796248840124,"bee_debug":3.8716796248840124,"bee_ollama_debug":3.8716796248840124,"txt":3.8716796248840124,"suggestion":3.8716796248840124,"suggest":3.8716796248840124,"five":3.8716796248840124,"topic":3.8716796248840124,"along":3.8716796248840124,"link":3.8716796248840124,"reference":3.8716796248840124,"contributing":3.8716796248840124,"interest":3.8716796248840124,"spot":3.8716796248840124,"discus":3.8716796248840124,"discussion":3.8716796248840124,"my_middleware":4.277144732992177,"mymiddleware":4.277144732992177},"sections":[{"label":"Production ready","body":"Take a look at the ru.Bee demo site with full documentation: https://rubee.dedyn.io/\nWant to explore how it was built? https://github.com/nucleom42/rubee-site","parent":null,"vector":{"producte":0.18943978299992545,"ready":0.2202395042168432,"take":0.28028478331534634,"look":0.28028478331534634,"demo":0.2537143240340849,"site":0.4404790084336864,"full":0.17481700405913278,"documentate":0.18943978299992545,"http":0.28803456568443003,"dedyn":0.2202395042168432,"want":0.2082918238763745,"explore":0.23486228315763585,"built":0.2082918238763745,"github":0.23486228315763585,"com":0.16286932371866403,"nucleom42":0.28028478331534634}},{"label":"Stress tested","body":"CODE>wrk -t4 -c100 -d30s https://rubee.dedyn.io/docs\nCODE>Running 30s test @ https://rubee.dedyn.io/docs\nCODE> 4 threads and 100 connections\nCODE> Thread Stats Avg Stdev Max +/- Stdev\nCODE> Latency 304.95ms 33.22ms 551.86ms 90.38%\nCODE> Req/Sec 82.25 42.37 280.00 69.86%\nCODE> 9721 requests in 30.02s, 4.11MB read\nCODE>Requests/sec: 323.78\nCODE>Transfer/sec: 140.07KB\n\nShort output explanation:\n • Requests/sec: ~324\n • Average latency: ~305 ms\n • Total requests handled: 9,721\n • Hardware: Raspberry Pi 5 (8 GB) — single board computer\n • Server: ru.Bee app hosted via Nginx + HTTPS\n\nThis demonstrates ru.Bee's efficient architecture and suitability for lightweight deployments — even on low-power hardware.","parent":null,"vector":{"stres":0.09676492392590892,"test":0.09944044234869472,"code":0.2369306341716474,"wrk":0.09676492392590892,"c100":0.09676492392590892,"d30":0.09676492392590892,"http":0.14916066352304208,"dedyn":0.15207003832987515,"doc":0.19352984785181784,"running":0.05819718078038106,"30":0.09676492392590892,"thread":0.19352984785181784,"100":0.08108335634205506,"connection":0.08108335634205506,"stat":0.09676492392590892,"avg":0.09676492392590892,"stdev":0.19352984785181784,"max":0.07603501916493757,"latency":0.19352984785181784,"304":0.09676492392590892,"95m":0.09676492392590892,"22m":0.09676492392590892,"551":0.09676492392590892,"86m":0.09676492392590892,"req":0.09676492392590892,"sec":0.3870596957036357,"280":0.09676492392590892,"9721":0.09676492392590892,"request":0.35036717974731985,"02":0.09676492392590892,"11mb":0.09676492392590892,"read":0.0719102273529761,"323":0.09676492392590892,"transfer":0.09676492392590892,"140":0.09676492392590892,"07kb":0.09676492392590892,"short":0.08759179493682996,"output":0.0719102273529761,"explanate":0.09676492392590892,"324":0.09676492392590892,"average":0.09676492392590892,"305":0.09676492392590892,"total":0.08108335634205506,"handl":0.09676492392590892,"721":0.09676492392590892,"hardware":0.19352984785181784,"raspberry":0.09676492392590892,"single":0.06540178875820121,"board":0.09676492392590892,"computer":0.09676492392590892,"server":0.052741197983797825,"app":0.04834866671820428,"host":0.08108335634205506,"nginx":0.09676492392590892,"demonstrates":0.09676492392590892,"efficient":0.08759179493682996,"architecture":0.09676492392590892,"suitability":0.09676492392590892,"lightweight":0.08759179493682996,"deployment":0.09676492392590892,"even":0.09676492392590892,"low":0.07603501916493757,"power":0.08759179493682996}},{"label":"Comparison","body":"Here is a short web frameworks comparison built with Ruby, so you can evaluate your choice with ru.Bee.\n\nDisclaimer:\nThe comparison is based on generic and subjective information available on the internet and is not a real benchmark. It is aimed at giving you a general idea of the differences between the frameworks and is not intended as a direct comparison.","parent":null,"vector":{"comparison":0.6353626127854158,"here":0.14378286426453646,"short":0.14378286426453646,"web":0.11804140406280747,"framework":0.23608280812561494,"built":0.11804140406280747,"ruby":0.0922999438610785,"evaluate":0.15884065319635396,"choice":0.15884065319635396,"disclaimer":0.15884065319635396,"bas":0.11804140406280747,"generic":0.15884065319635396,"subjective":0.15884065319635396,"informate":0.15884065319635396,"available":0.10298361513098997,"internet":0.14378286426453646,"not":0.184599887722157,"real":0.15884065319635396,"benchmark":0.15884065319635396,"aim":0.15884065319635396,"giving":0.15884065319635396,"general":0.15884065319635396,"idea":0.13309919299462497,"differences":0.15884065319635396,"between":0.15884065319635396,"intend":0.15884065319635396,"direct":0.11231669839980915}},{"label":"Features","body":"Lightweight – A minimal footprint focused on serving Ruby applications efficiently.\n\nModular – A modular approach to application development. Build a modular monolith app with ease by attaching as many subprojects as you need.\n\nContract-driven – Define your API contracts in a simple, declarative way, then generate all the boilerplate you need.\n\nFast – Optimized for speed, providing quick responses.\n\nRack-powered – Built on Rack. The full Rack API is available for easy integration.\n\nDatabases – Supports SQLite3, PostgreSQL, MySQL, and more via the Sequel gem.\n\nViews – JSON, ERB, and plain HTML out of the box.\n\nReact Ready – React is supported as a first-class ru.Bee view engine.\n\nBundlable – Charge your ru.Bee app with any gem you need. Update effortlessly via Bundler.\n\nORM-agnostic – Models are native ORM objects, but you can use them as blueprints for any data source.\n\nAuthenticatable – Easily add JWT authentication to any controller action.\n\nHooks – Add logic before, after, or around any controller action.\n\nTestable – Run all or selected tests using fast, beloved Minitest.\n\nAsyncable – Plug in async adapters and use any popular background job engine.\n\nConsole – Start an interactive console and reload on the fly.\n\nBackground Jobs – Schedule and process background jobs using your preferred async stack.\n\nWebSocket – Serve and handle WebSocket connections.\n\nLogger – Use any logger you want.","parent":null,"vector":{"features":0.08322376132731645,"lightweight":0.07533430855209043,"minimal":0.08322376132731645,"footprint":0.08322376132731645,"focus":0.08322376132731645,"serving":0.08322376132731645,"ruby":0.04836009134842457,"applicate":0.0697366527254835,"efficient":0.07533430855209043,"modular":0.20920995817645052,"approach":0.08322376132731645,"applicat":0.05395774717503148,"development":0.04680263757604442,"build":0.056249544123650574,"monolith":0.08322376132731645,"app":0.08316562936649889,"ease":0.07533430855209043,"attaching":0.08322376132731645,"many":0.0618471999502575,"subproject":0.0697366527254835,"ne":0.1765433076344047,"contract":0.15066861710418086,"driven":0.08322376132731645,"define":0.0618471999502575,"api":0.13078954709551296,"simple":0.06539477354775648,"declarative":0.08322376132731645,"way":0.07533430855209043,"then":0.056249544123650574,"generate":0.041582814683249446,"all":0.09072132121927061,"boilerplate":0.08322376132731645,"fast":0.1664475226546329,"optimiz":0.08322376132731645,"spe":0.07533430855209043,"providing":0.08322376132731645,"quick":0.08322376132731645,"responses":0.07533430855209043,"rack":0.16187324152509447,"power":0.07533430855209043,"built":0.0618471999502575,"full":0.05190766494592355,"available":0.05395774717503148,"easy":0.08322376132731645,"integrate":0.0697366527254835,"databases":0.06539477354775648,"support":0.08803642434139507,"sqlite3":0.07533430855209043,"postgresql":0.07533430855209043,"mysql":0.08322376132731645,"more":0.05884776921146824,"sequel":0.05884776921146824,"gem":0.11249908824730115,"view":0.08552487104363529,"json":0.044018212170697534,"erb":0.056249544123650574,"plain":0.07533430855209043,"html":0.07533430855209043,"box":0.0697366527254835,"react":0.11769553842293648,"ready":0.06539477354775648,"first":0.04836009134842457,"clas":0.0374712078344093,"engine":0.1038153298918471,"bundlable":0.08322376132731645,"charge":0.08322376132731645,"any":0.2901605480905474,"update":0.05190766494592355,"effortles":0.08322376132731645,"bundler":0.07533430855209043,"orm":0.139473305450967,"agnostic":0.08322376132731645,"model":0.03842055634409061,"native":0.08322376132731645,"object":0.04680263757604442,"but":0.08322376132731645,"them":0.0697366527254835,"blueprint":0.08322376132731645,"data":0.056249544123650574,"source":0.08322376132731645,"authenticatable":0.08322376132731645,"easi":0.08322376132731645,"add":0.09360527515208884,"jwt":0.06539477354775648,"authenticat":0.05395774717503148,"controller":0.09360527515208884,"acte":0.11769553842293648,"hook":0.05884776921146824,"logic":0.0618471999502575,"before":0.05005313998797345,"after":0.056249544123650574,"around":0.07533430855209043,"testable":0.08322376132731645,"select":0.08322376132731645,"test":0.042762435521817646,"belov":0.08322376132731645,"minitest":0.08322376132731645,"asyncable":0.06539477354775648,"plug":0.07533430855209043,"async":0.13078954709551296,"adapter":0.0697366527254835,"popular":0.08322376132731645,"background":0.19618432064326943,"job":0.18554159985077248,"console":0.15066861710418086,"start":0.03941861022262161,"interactive":0.05884776921146824,"reload":0.06539477354775648,"f":0.08322376132731645,"schedule":0.07533430855209043,"proces":0.06539477354775648,"preferr":0.08322376132731645,"stack":0.07533430855209043,"websocket":0.13078954709551296,"serve":0.08322376132731645,"handle":0.0697366527254835,"connection":0.0697366527254835,"logger":0.139473305450967,"want":0.0618471999502575}},{"label":"Installation","body":"1. Install ru.Bee\n\nCODE>gem install ru.Bee\n\n2. Create your first project\n\nCODE>rubee project my_project\nCODE>\nCODE>cd my_project\n\n3. Install dependencies\n\nPrerequisites: make sure Ruby (3.1 or higher, 3.4.1 recommended) and Bundler are installed.\n\nCODE>bundle install\n\n4. Run the ru.Bee server. Default port is 7000.\n\nCODE>rubee start # or rubee start_dev for development\nCODE>\nCODE># Starting from version 1.8.0, you can also start the server with the yjit compiler for a speed boost.\nCODE>rubee start --jit=yjit\nCODE># This option is available for the dev environment too.\nCODE>rubee start_dev --jit=yjit\n\n5. Open your browser and go to http://localhost:7000","parent":null,"vector":{"installate":0.11344756253757744,"install":0.3537930737095515,"code":0.33950689787850563,"gem":0.07667730432875208,"create":0.05668415959611314,"first":0.06592269323175352,"project":0.3565749753852919,"my_project":0.22689512507515489,"dependency":0.0843078223361662,"prerequisites":0.09506243343316474,"ruby":0.06592269323175352,"higher":0.09506243343316474,"recommend":0.09506243343316474,"bundler":0.10269295144057888,"bundle":0.09506243343316474,"server":0.12366795970727996,"default":0.06000400364491175,"port":0.09506243343316474,"7000":0.19012486686632948,"start":0.2686699794057153,"start_dev":0.16043821791610532,"dev":0.23003191298625625,"development":0.06379962968086966,"starting":0.08021910895805266,"version":0.07667730432875208,"yjit":0.34034268761273234,"compiler":0.11344756253757744,"spe":0.10269295144057888,"boost":0.11344756253757744,"jit":0.22689512507515489,"opte":0.11344756253757744,"available":0.07355321123916765,"environment":0.0707586147419103,"too":0.11344756253757744,"open":0.0843078223361662,"browser":0.09506243343316474,"http":0.05829217522433939,"localhost":0.07667730432875208}},{"label":"Run tests","body":"CODE>rubee test\nCODE># or specify a specific test file\nCODE>rubee test models/user_model_test.rb\nCODE># or run a specific line in the test file\nCODE>rubee test models/user_model_test.rb --line=12","parent":null,"vector":{"test":0.7188294853984609,"code":0.23787650875642707,"specify":0.17487221201805964,"specific":0.21034625613042457,"file":0.20323128906019908,"model":0.3229216064114782,"user_model_test":0.31658932418453517,"user":0.1747500634343501,"line":0.27481883833007514}},{"label":"Draw contract","body":"1. Add the routes to routes.rb\n\nCODE> Rubee::Router.draw do |router|\nCODE> ...\nCODE> # draw the contract\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE> end\nCODE>\n\n2. Generate the files\n\nCODE>rubee generate get /apples\n\nThis will generate the following files:\n\nCODE>./app/controllers/apples_controller.rb # Controller with respective action\nCODE>./app/views/apples_index.erb # ERB view rendered by the controller\nCODE>./app/models/apple.rb # Model that acts as ORM\nCODE>./db/create_apples.rb # Database migration file for the respective table\n\n3. Run the initial database migration\n\nCODE>rubee db run:all\n\n4. Fill the generated files with the logic you need and run the server again.\n\n5. You can find a full snapshot of the schema in the STRUCTURE constant or in the db/structure.rb file.\n\n6. Print the latest schema from the STRUCTURE constant via the CLI\n\nCODE>-> rubee db schema\nCODE>--- users\nCODE>- id, (PK), type (INTEGER)\nCODE>- email, type (varchar(255))\nCODE>- password, type (varchar(255))\nCODE>\nCODE>--- accounts\nCODE>- id, (PK), type (INTEGER)\nCODE>- address, type (varchar(255))\nCODE>- user_id, type (INTEGER)\nCODE>\nCODE>--- posts\nCODE>- id, (PK), type (INTEGER)\nCODE>- user_id, type (INTEGER)\nCODE>- comment_id, type (INTEGER)\nCODE>\nCODE>--- comments\nCODE>- id, (PK), type (INTEGER)\nCODE>- text, type (varchar(255))\nCODE>- user_id, type (INTEGER)\n\n7. Print the schema for a specific table\n\nCODE>-> rubee db schema posts\nCODE>--- posts\nCODE>- id, (PK), type (INTEGER)\nCODE>- user_id, type (INTEGER), nullable\nCODE>- comment_id, type (INTEGER), nullable\nCODE>- created, type (datetime), nullable\nCODE>- updated, type (datetime), nullable\nCODE>\nCODE> Foreign keys:\nCODE> - comment_id → comments() on delete no_action on update no_action\nCODE> - user_id → users() on delete no_action on update no_action\n\n8. Dropping all tables can be handy during development. Be careful and make sure you pass the desired environment.\n\nCODE>RACK_ENV=test rubee db drop_tables\nCODE>These tables have been dropped for the test env:\nCODE>[:companies, :company_clients, :services]","parent":null,"vector":{"draw":0.07072835369929924,"contract":0.06583264251415362,"add":0.020449788200636025,"routes":0.04226059370401303,"code":0.554006168978416,"router":0.06804108544581493,"apples":0.14145670739859847,"index":0.043740103743843385,"model":0.05036204883820948,"name":0.11539902396297838,"apple":0.054046618109083316,"attributes":0.024577488006781764,"type":0.43603418318502873,"primary":0.027023309054541658,"colour":0.027023309054541658,"string":0.021870051871921693,"weight":0.024577488006781764,"integer":0.3242797086545,"creat":0.05142549560370927,"datetime":0.10809323621816663,"updat":0.04915497601356353,"end":0.015977039669386548,"generate":0.054507168640469915,"files":0.081069927163625,"app":0.054507168640469915,"controller":0.0817991528025441,"apples_controller":0.030470500209316905,"respective":0.07272702482370412,"acte":0.12856373900927318,"view":0.03736895160849323,"apples_index":0.030470500209316905,"erb":0.04915497601356353,"render":0.025712747801854636,"act":0.03636351241185206,"orm":0.030470500209316905,"create_apples":0.02857337401780679,"create":0.01816905621348997,"database":0.04089957640127205,"migrate":0.04915497601356353,"file":0.04226059370401303,"table":0.06094100041863381,"initial":0.030470500209316905,"all":0.03963947119863897,"fill":0.030470500209316905,"generat":0.024577488006781764,"logic":0.027023309054541658,"ne":0.025712747801854636,"server":0.019819735599319484,"again":0.03636351241185206,"find":0.025712747801854636,"full":0.02268036181527164,"snapshot":0.03636351241185206,"schema":0.15235250104658452,"structure":0.08572012205342038,"constant":0.07272702482370412,"print":0.06094100041863381,"latest":0.03291632125707681,"cli":0.027023309054541658,"user":0.1271833934944298,"email":0.021130296852006514,"varchar":0.14545404964740824,"255":0.14545404964740824,"password":0.021130296852006514,"account":0.03291632125707681,"addres":0.03636351241185206,"user_id":0.15235250104658452,"post":0.07373246402034529,"comment_id":0.09141150062795073,"comment":0.15235250104658452,"text":0.027023309054541658,"specific":0.021870051871921693,"nullable":0.14545404964740824,"foreign":0.030470500209316905,"key":0.02268036181527164,"delete":0.06094100041863381,"no_acte":0.14545404964740824,"update":0.04536072363054328,"dropping":0.03636351241185206,"tables":0.10909053723555619,"handy":0.03636351241185206,"during":0.03636351241185206,"development":0.020449788200636025,"careful":0.03636351241185206,"pas":0.024577488006781764,"desir":0.03291632125707681,"environment":0.02268036181527164,"rack_env":0.030470500209316905,"rack":0.02357611789976641,"env":0.04089957640127205,"test":0.03736895160849323,"drop_tables":0.03636351241185206,"drop":0.03636351241185206,"dropp":0.03636351241185206,"company":0.07272702482370412,"company_client":0.03636351241185206,"client":0.025712747801854636,"services":0.03291632125707681}},{"label":"Model","body":"A model in ru.Bee is a simple Ruby object that can be serialized in the view in whatever form is required (e.g. JSON).\nHere is a simple example of rendering JSON from an in-memory object:\n\nCODE># ApplesController\nCODE>\nCODE>def show\nCODE> # In-memory example\nCODE> apples = [Apple.new(colour: 'red', weight: '1lb'), Apple.new(colour: 'green', weight: '1lb')]\nCODE> apple = apples.find { |apple| apple.colour = params[:colour] }\nCODE>\nCODE> response_with object: apple, type: :json\nCODE>end\n\nMake sure the Serializable module is included in the target class:\n\nCODE>class Apple\nCODE> include Serializable\nCODE> attr_accessor :id, :colour, :weight\nCODE>end\n\nYou can also turn it into an ORM object by extending Rubee::SequelObject, which is already serializable and charged with hooks:\n\nCODE>class Apple user = User.new(email: \"llo@ok.com\", password: 543)\nCODE>=> #\n\nSave a record to the database\n\nCODE>irb(main):018> user.save\nCODE>=> true\n\nUpdate a record with a new value\n\nCODE>irb(main):019> user.update(email: \"update@email.com\")\nCODE>=> #\n\nCheck whether a record has been persisted\n\nCODE>irb(main):016> user.persisted?\nCODE>=> false\n\nGet a record from the database and reload it\n\nCODE>irb(main):011> user = User.last\nCODE>=> #\nCODE>irb(main):012> user.email = \"new@ok.com\"\nCODE>=> \"new@ok.com\"\nCODE>irb(main):014> user.reload\nCODE>=> # # unpersisted data refreshed from db\n\nAssign attributes without persisting to the database\n\nCODE>irb(main):008> User.last.assign_attributes(email: \"bb@ok.com\")\nCODE>=> {\"id\" => 2, \"email\" => \"ok23@ok.com\", \"password\" => \"123\"}\n\nGet all records scoped by a field\n\nCODE>irb(main):005> User.where(email: \"ok23@ok.com\")\nCODE>=> [#]\n\nGet all records\n\nCODE>irb(main):001> User.all\nCODE>=> [#]\n\nFind by id\n\nCODE>irb(main):002> user = User.find 1\nCODE>=> #\n\nGet the last record\n\nCODE>irb(main):003> User.last\nCODE>=> #\n\nCreate a new persisted record\n\nCODE>irb(main):004> User.create(email: \"ok23@ok.com\", password: 123)\nCODE>=> #\n\nDestroy a record and all related records\n\nCODE>irb(main):021> user.destroy(cascade: true)\nCODE>=> 1\n\nFind a record in the database or initialize a new instance for subsequent persistence\n\nCODE>irb(main):020> user = User.find_or_new(email: \"ok23@ok.com\")\nCODE>=> #\nCODE>irb(main):021> user.persisted?\nCODE>=> true\nCODE>irb(main):022> user = User.find_or_new(email: \"new@ok.com\")\nCODE>=> #\nCODE>irb(main):023> user.persisted?\nCODE>=> false\n\nDestroy all records one by one\n\nCODE>irb(main):022> User.destroy_all\nCODE>=> [#, #]\nCODE>irb(main):023> User.all\nCODE>=> []\n\nUse complex query chains and serialize results back to ru.Bee objects in a single query:\n\nCODE># user model\nCODE>class User result = Comment.dataset.join(:posts, comment_id: :id)\nCODE>irb(main):009> .where(comment_id: Comment.where(text: \"test\").last.id)\nCODE>irb(main):010> .then { |dataset| Comment.serialize(dataset) }\nCODE>=> [#]\n\nSince version 2.6.0, Rubee::SequelObject supports chained queries. Supported methods: where, order, limit, offset, all, owns_many, owns_one, join, paginate.\n\nCODE>irb(main):001> Comment.where(text: \"test\").where(user_id: 1)\nCODE>=> [#]\n\nA paginate method is also available:\n\nCODE>irb(main):001> comments = Comment.all.paginate(page: 1, per_page: 3)\nCODE>\nCODE>irb(main):001> comments.pagination_meta\nCODE>=> {:current_page=>1, :per_page=>3, :total_count=>10, :first_page=>true, :last_page=>false, :prev=>nil, :next=>2}","parent":null,"vector":{"model":0.032709218341639944,"simple":0.03711575486169249,"ruby":0.01372373660921379,"object":0.0664087941937945,"serializ":0.02361742809489898,"view":0.012135221119449585,"whatever":0.02361742809489898,"form":0.02361742809489898,"requir":0.015312252098977994,"json":0.037474764810932565,"here":0.021378541259513387,"rendering":0.02361742809489898,"memory":0.042757082519026775,"code":0.4112191430256297,"applescontroller":0.021378541259513387,"def":0.012491588270310855,"apples":0.03062450419795599,"apple":0.1404091114749087,"new":0.1509611027013517,"colour":0.08775569467181796,"r":0.02361742809489898,"weight":0.047887870333798155,"1lb":0.04723485618979796,"green":0.02361742809489898,"find":0.10019972198306863,"param":0.01979002576974918,"response_with":0.015312252098977994,"response":0.014204193799179657,"type":0.012872551338694974,"end":0.020753582948059717,"serializable":0.07085228428469695,"module":0.018557877430846244,"includ":0.02361742809489898,"target":0.021378541259513387,"clas":0.04253465801323753,"include":0.012872551338694974,"attr_accessor":0.021378541259513387,"attr":0.021378541259513387,"accessor":0.021378541259513387,"turn":0.02361742809489898,"orm":0.01979002576974918,"extending":0.02361742809489898,"sequelobject":0.03958005153949836,"already":0.02361742809489898,"charg":0.01979002576974918,"hook":0.01669995366384477,"user":0.33041303784954723,"email":0.1372373660921379,"llo":0.021378541259513387,"com":0.1372373660921379,"password":0.04117120982764137,"543":0.021378541259513387,"save":0.03958005153949836,"record":0.22269452917015495,"database":0.05312703535503559,"irb":0.4749606184739803,"main":0.3535314025367147,"018":0.021378541259513387,"true":0.05489494643685516,"update":0.04419142531708934,"value":0.01979002576974918,"019":0.021378541259513387,"check":0.018557877430846244,"whether":0.021378541259513387,"persist":0.0989501288487459,"016":0.021378541259513387,"false":0.050099860991534316,"reload":0.03711575486169249,"011":0.021378541259513387,"last":0.09577574066759631,"012":0.021378541259513387,"014":0.021378541259513387,"unpersist":0.021378541259513387,"data":0.015962623444599384,"refresh":0.021378541259513387,"assign":0.042757082519026775,"attributes":0.03192524688919877,"without":0.018557877430846244,"persisting":0.021378541259513387,"008":0.021378541259513387,"assign_attributes":0.021378541259513387,"ok23":0.08551416503805355,"123":0.03339990732768954,"all":0.11585296204825477,"scop":0.021378541259513387,"field":0.01979002576974918,"005":0.021378541259513387,"001":0.08551416503805355,"002":0.021378541259513387,"003":0.021378541259513387,"create":0.02360093127496766,"004":0.021378541259513387,"destroy":0.08551416503805355,"relat":0.018557877430846244,"021":0.042757082519026775,"cascade":0.021378541259513387,"initialize":0.015962623444599384,"instance":0.021378541259513387,"subsequent":0.021378541259513387,"persistence":0.01979002576974918,"020":0.021378541259513387,"find_or_new":0.042757082519026775,"022":0.042757082519026775,"023":0.042757082519026775,"one":0.039845276516276694,"destroy_all":0.021378541259513387,"complex":0.021378541259513387,"query":0.06413562377854017,"chain":0.042757082519026775,"serialize":0.042757082519026775,"result":0.03711575486169249,"back":0.021378541259513387,"single":0.015962623444599384,"comment":0.1781102319277426,"dataset":0.05937007730924754,"join":0.03958005153949836,"post":0.015962623444599384,"comment_id":0.03958005153949836,"009":0.021378541259513387,"text":0.035102277868727175,"test":0.02427044223889917,"010":0.021378541259513387,"then":0.015962623444599384,"since":0.021378541259513387,"version":0.015962623444599384,"support":0.02498317654062171,"method":0.02744747321842758,"order":0.021378541259513387,"limit":0.021378541259513387,"offset":0.021378541259513387,"owns_many":0.021378541259513387,"own":0.035102277868727175,"many":0.017551138934363587,"owns_one":0.021378541259513387,"paginate":0.08551416503805355,"user_id":0.01979002576974918,"available":0.015312252098977994,"page":0.12827124755708033,"per_page":0.042757082519026775,"per":0.042757082519026775,"pagination_meta":0.021378541259513387,"meta":0.021378541259513387,"current_page":0.021378541259513387,"current":0.018557877430846244,"total_count":0.021378541259513387,"total":0.01979002576974918,"count":0.021378541259513387,"first_page":0.021378541259513387,"first":0.01372373660921379,"last_page":0.021378541259513387,"prev":0.021378541259513387,"nil":0.021378541259513387,"next":0.018557877430846244}},{"label":"Model — Rubee::SequelObject base methods","body":"Initiate a new record in memory\n\nCODE>irb(main):015> user = User.new(email: \"llo@ok.com\", password: 543)\nCODE>=> #\n\nSave a record to the database\n\nCODE>irb(main):018> user.save\nCODE>=> true\n\nUpdate a record with a new value\n\nCODE>irb(main):019> user.update(email: \"update@email.com\")\nCODE>=> #\n\nCheck whether a record has been persisted\n\nCODE>irb(main):016> user.persisted?\nCODE>=> false\n\nGet a record from the database and reload it\n\nCODE>irb(main):011> user = User.last\nCODE>=> #\nCODE>irb(main):012> user.email = \"new@ok.com\"\nCODE>=> \"new@ok.com\"\nCODE>irb(main):014> user.reload\nCODE>=> # # unpersisted data refreshed from db\n\nAssign attributes without persisting to the database\n\nCODE>irb(main):008> User.last.assign_attributes(email: \"bb@ok.com\")\nCODE>=> {\"id\" => 2, \"email\" => \"ok23@ok.com\", \"password\" => \"123\"}\n\nGet all records scoped by a field\n\nCODE>irb(main):005> User.where(email: \"ok23@ok.com\")\nCODE>=> [#]\n\nGet all records\n\nCODE>irb(main):001> User.all\nCODE>=> [#]\n\nFind by id\n\nCODE>irb(main):002> user = User.find 1\nCODE>=> #\n\nGet the last record\n\nCODE>irb(main):003> User.last\nCODE>=> #\n\nCreate a new persisted record\n\nCODE>irb(main):004> User.create(email: \"ok23@ok.com\", password: 123)\nCODE>=> #\n\nDestroy a record and all related records\n\nCODE>irb(main):021> user.destroy(cascade: true)\nCODE>=> 1\n\nFind a record in the database or initialize a new instance for subsequent persistence\n\nCODE>irb(main):020> user = User.find_or_new(email: \"ok23@ok.com\")\nCODE>=> #\nCODE>irb(main):021> user.persisted?\nCODE>=> true\nCODE>irb(main):022> user = User.find_or_new(email: \"new@ok.com\")\nCODE>=> #\nCODE>irb(main):023> user.persisted?\nCODE>=> false\n\nDestroy all records one by one\n\nCODE>irb(main):022> User.destroy_all\nCODE>=> [#, #]\nCODE>irb(main):023> User.all\nCODE>=> []\n\nUse complex query chains and serialize results back to ru.Bee objects in a single query:\n\nCODE># user model\nCODE>class User result = Comment.dataset.join(:posts, comment_id: :id)\nCODE>irb(main):009> .where(comment_id: Comment.where(text: \"test\").last.id)\nCODE>irb(main):010> .then { |dataset| Comment.serialize(dataset) }\nCODE>=> [#]\n\nSince version 2.6.0, Rubee::SequelObject supports chained queries. Supported methods: where, order, limit, offset, all, owns_many, owns_one, join, paginate.\n\nCODE>irb(main):001> Comment.where(text: \"test\").where(user_id: 1)\nCODE>=> [#]\n\nA paginate method is also available:\n\nCODE>irb(main):001> comments = Comment.all.paginate(page: 1, per_page: 3)\nCODE>\nCODE>irb(main):001> comments.pagination_meta\nCODE>=> {:current_page=>1, :per_page=>3, :total_count=>10, :first_page=>true, :last_page=>false, :prev=>nil, :next=>2}","parent":"Model","vector":{"model":0.022842931496881328,"sequelobject":0.041461908223383574,"base":0.013085508135608853,"method":0.04312871906232413,"initiate":0.02474033251740109,"new":0.14376239687441378,"record":0.25272289327817044,"memory":0.022394996498859975,"code":0.34327047927928034,"irb":0.5182738527922947,"main":0.3857711038537491,"015":0.02474033251740109,"user":0.3461227188513388,"email":0.14376239687441378,"llo":0.022394996498859975,"com":0.14376239687441378,"password":0.04312871906232413,"543":0.022394996498859975,"save":0.041461908223383574,"database":0.055652991302265954,"018":0.022394996498859975,"true":0.05750495874976551,"update":0.046292532462449895,"value":0.020730954111691787,"019":0.022394996498859975,"check":0.019440222559859263,"whether":0.022394996498859975,"persist":0.10365477055845895,"016":0.022394996498859975,"false":0.05248188816435275,"reload":0.038880445119718526,"011":0.022394996498859975,"last":0.10032945423589494,"012":0.022394996498859975,"014":0.022394996498859975,"unpersist":0.022394996498859975,"data":0.016721575705982494,"refresh":0.022394996498859975,"assign":0.04478999299771995,"attributes":0.03344315141196499,"without":0.019440222559859263,"persisting":0.022394996498859975,"008":0.022394996498859975,"assign_attributes":0.022394996498859975,"ok23":0.0895799859954399,"123":0.034987925442901836,"all":0.12136125884167455,"scop":0.022394996498859975,"field":0.020730954111691787,"005":0.022394996498859975,"001":0.0895799859954399,"find":0.08746981360725459,"002":0.022394996498859975,"003":0.022394996498859975,"create":0.024723051346524198,"004":0.022394996498859975,"destroy":0.0895799859954399,"relat":0.019440222559859263,"021":0.04478999299771995,"cascade":0.022394996498859975,"initialize":0.016721575705982494,"instance":0.022394996498859975,"subsequent":0.022394996498859975,"persistence":0.020730954111691787,"020":0.022394996498859975,"find_or_new":0.04478999299771995,"022":0.04478999299771995,"023":0.04478999299771995,"one":0.04173974347669946,"destroy_all":0.022394996498859975,"complex":0.022394996498859975,"query":0.06718498949657993,"chain":0.04478999299771995,"serialize":0.04478999299771995,"result":0.038880445119718526,"back":0.022394996498859975,"object":0.013913247825566489,"single":0.016721575705982494,"clas":0.011139248297200505,"comment":0.1865785870052261,"dataset":0.062192862335075365,"join":0.041461908223383574,"post":0.016721575705982494,"comment_id":0.041461908223383574,"009":0.022394996498859975,"text":0.036771236186301355,"test":0.025424394600546383,"010":0.022394996498859975,"then":0.016721575705982494,"since":0.022394996498859975,"version":0.016721575705982494,"support":0.026171016271217706,"order":0.022394996498859975,"limit":0.022394996498859975,"offset":0.022394996498859975,"owns_many":0.022394996498859975,"own":0.036771236186301355,"many":0.018385618093150678,"owns_one":0.022394996498859975,"paginate":0.0895799859954399,"user_id":0.020730954111691787,"available":0.01604028207460956,"page":0.13436997899315986,"per_page":0.04478999299771995,"per":0.04478999299771995,"pagination_meta":0.022394996498859975,"meta":0.022394996498859975,"current_page":0.022394996498859975,"current":0.019440222559859263,"total_count":0.022394996498859975,"total":0.020730954111691787,"count":0.022394996498859975,"first_page":0.022394996498859975,"first":0.014376239687441377,"last_page":0.022394996498859975,"prev":0.022394996498859975,"nil":0.022394996498859975,"next":0.019440222559859263}},{"label":"Database","body":"ru.Bee supports Postgres and SQLite databases fully and can potentially be used with any database supported by the Sequel gem.\n\nWhen using SQLite, include sqlite3 in your Gemfile:\n\nCODE>gem 'sqlite3'\n\nDefine your database URLs for each environment in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :test) do |config|\nCODE> config.database_url = { url: 'sqlite://db/test.db', env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :production) do |config|\nCODE> config.database_url = { url: 'sqlite://db/production.db', env: }\nCODE> ...\nCODE>end\n\nFor PostgreSQL, include the pg gem and configure the URLs:\n\nCODE>gem 'pg'\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"postgres://postgres@localhost:5432/development\", env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :test) do |config|\nCODE> config.database_url = { url: \"postgres://postgres@localhost:5432/test\", env: }\nCODE> ...\nCODE>end\nCODE>Rubee::Configuration.setup(env = :production) do |config|\nCODE> config.database_url = { url: \"postgres://postgres:#{ENV['DB_PASSWORD']}@localhost:5432/production\", env: }\nCODE> ...\nCODE>end\n\nBefore starting the server or running the test suite, ensure your database is initialized:\n\nCODE>rubee db init # ensures your database is created for each environment\nCODE>RACK_ENV=test rubee db run:all # runs all migrations for the test environment\nCODE>RACK_ENV=development rubee db run:all # runs all migrations for the development environment\n\nSQLite production ready\n\nStarting from version 1.9.0, the main issue with SQLite — write database locking — is resolved.\nYou can tune the retry configuration parameters as needed:\n\n```ruby","parent":null,"vector":{"database":0.28879066543372267,"support":0.04526827775223897,"postgres":0.29955526477529737,"sqlite":0.211816418849972,"databases":0.033625954196241266,"ful":0.04279360925361391,"potential":0.04279360925361391,"us":0.0358585459223865,"any":0.024866730602264728,"sequel":0.030259488407138855,"gem":0.11569393036463642,"include":0.04664885015182291,"sqlite3":0.07747371452943906,"gemfile":0.033625954196241266,"code":0.33762738312393353,"define":0.03180179393349213,"url":0.3603221330735758,"each":0.06360358786698427,"environment":0.10676356346005543,"config":0.30321752598684887,"base_configurate":0.027745041944597756,"base":0.022634138876119484,"configurate":0.205898361756329,"setup":0.16014534519008314,"env":0.36098833179215334,"development":0.14439533271686134,"database_url":0.19081076360095278,"end":0.11281339132988234,"test":0.1539189348195219,"producte":0.14461741295579553,"postgresql":0.03873685726471953,"configure":0.027745041944597756,"localhost":0.08677044777347731,"5432":0.12838082776084175,"db_password":0.04279360925361391,"password":0.024866730602264728,"before":0.025737295219541125,"starting":0.06051897681427771,"server":0.023324425075911454,"running":0.025737295219541125,"suite":0.04279360925361391,"ensure":0.0358585459223865,"initializ":0.04279360925361391,"init":0.028923482591159105,"ensures":0.04279360925361391,"creat":0.030259488407138855,"rack_env":0.071717091844773,"rack":0.05549008388919551,"all":0.09329770030364581,"run":0.08558721850722782,"migrate":0.05784696518231821,"ready":0.033625954196241266,"version":0.028923482591159105,"main":0.026690890865013858,"issue":0.033625954196241266,"write":0.028923482591159105,"locking":0.03873685726471953,"resolv":0.03873685726471953,"tune":0.03873685726471953,"retry":0.028923482591159105,"parameter":0.0358585459223865,"need":0.030259488407138855,"ruby":0.024866730602264728}},{"label":"Database — SQLite production ready","body":"Starting from version 1.9.0, the main issue with SQLite — write database locking — is resolved.\nYou can tune the retry configuration parameters as needed:\n\n```ruby","parent":"Database","vector":{"database":0.3305797400823429,"sqlite":0.4156577760974351,"producte":0.19865290333193078,"ready":0.2309505228955955,"starting":0.20782888804871755,"version":0.19865290333193078,"main":0.1833189674216969,"issue":0.2309505228955955,"write":0.19865290333193078,"locking":0.26605334047647783,"resolv":0.26605334047647783,"tune":0.26605334047647783,"retry":0.19865290333193078,"configurate":0.1767694607023453,"parameter":0.2462844588058294,"need":0.20782888804871755,"ruby":0.17079022952868056}},{"label":"configure database write retries","body":"config.db_max_retries = { env:, value: 3 } # set to 0 to disable, or increase if needed\nconfig.db_retry_delay = { env:, value: 0.1 }\nconfig.db_busy_timeout = { env:, value: 1000 } # busy timeout in milliseconds before raising an error\n\nCODE>\nCODE>For ru.Bee model create and update methods, retries are added automatically. To use retries with a Sequel dataset directly:\nCODE>\nruby\nRubee::DBTools.with_retry { User.dataset.insert(email: \"test@ok.com\", password: \"123\") }\n```","parent":null,"vector":{"configure":0.0834280854089268,"database":0.07236503837699378,"write":0.08697160309785262,"retry":0.5218296185871157,"config":0.21040647167514667,"db_max_retry":0.1286784462209795,"max":0.10111172238421888,"env":0.21709511513098131,"value":0.3234750739782481,"disable":0.1286784462209795,"increase":0.1286784462209795,"need":0.09098891211994564,"db_retry_delay":0.1286784462209795,"delay":0.1286784462209795,"db_busy_timeout":0.1286784462209795,"busy":0.257356892441959,"timeout":0.257356892441959,"1000":0.1286784462209795,"millisecond":0.1286784462209795,"before":0.07739088187569762,"raising":0.1286784462209795,"error":0.08025830082265546,"code":0.10502382003180845,"model":0.05940487926109204,"create":0.06429428203672378,"update":0.08025830082265546,"method":0.074773133472608,"add":0.07236503837699378,"automatical":0.10782502465941603,"sequel":0.09098891211994564,"dataset":0.21565004931883205,"direct":0.09098891211994564,"ruby":0.074773133472608,"dbtool":0.1286784462209795,"with_retry":0.1286784462209795,"user":0.06429428203672378,"insert":0.1286784462209795,"email":0.074773133472608,"test":0.0661181815362892,"com":0.074773133472608,"password":0.074773133472608,"123":0.09098891211994564}},{"label":"Routing","body":"ru.Bee uses explicit routes. In routes.rb you can define routes for any of the main HTTP methods.\nYou can also include matched parameters denoted by { } in the route path, e.g. /path/to/{a_key}/somewhere.\n\nRouting methods\n\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/posts', to: 'posts#index'\nCODE> router.post '/posts', to: 'posts#create'\nCODE> router.patch '/posts/{id}', to: 'posts#update'\nCODE> router.put '/posts/{id}', to: 'posts#update'\nCODE> router.delete '/posts/{id}', to: 'posts#delete'\nCODE> router.head '/posts', to: 'posts#index'\nCODE> router.connect '/posts', to: 'posts#index'\nCODE> router.options '/posts', to: 'posts#index'\nCODE> router.trace '/posts', to: 'posts#index'\nCODE>end\n\nEvery route follows this structure:\n\nCODE>route.{http_method} {path}, to: \"{controller}#{action}\",\nCODE> model: { ...optional }, namespace: { ...optional }, react: { ...optional }\n\nDefining model attributes in routes\n\nOne of ru.Bee's unique traits is defining models for generation directly in the routes:\n\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE>end\n\nOther supported attribute types via Sequel:\n\nCODE>[\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'description', type: :text },\nCODE> { name: 'quantity', type: :integer },\nCODE> { name: 'created', type: :date },\nCODE> { name: 'modified', type: :datetime },\nCODE> { name: 'exists', type: :time },\nCODE> { name: 'active', type: :boolean },\nCODE> { name: 'hash', type: :bigint },\nCODE> { name: 'price', type: :decimal },\nCODE> { name: 'item_id', type: :foreign_key },\nCODE> { name: 'item_id_index', type: :index },\nCODE> { name: 'item_id_unique', type: :unique }\nCODE>]\n\nEvery attribute can carry options based on the Sequel schema definition. For example:\n\nCODE>{ name: 'key', type: :string, options: { size: 50, fixed: true } }\n\nGets translated to:\n\nCODE>String :key, size: 50, fixed: true\n\nGeneration from routes\n\nAs long as a route has a model: key, you can use it to generate initial model files. If only path and to: are defined, only a controller and view will be generated.\n\nCODE>rubee generate get /apples # or: rubee gen get /apples\nCODE>rubee generate patch /apples/{id} # or: rubee gen patch /apples/{id}\n\nExample 1 — route without a model:\n\nCODE>router.get \"/apples\", to: \"apples#index\"\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\n\nExample 2 — route with a model name only:\n\nCODE>router.get \"/apples\", to: \"apples#index\", model: { name: 'apple' }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\nCODE>./app/models/apple.rb\nCODE>./db/create_apples.rb\n\nExample 3 — route with full model attributes:\n\nCODE>router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: 'apple',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/models/apple.rb\nCODE>./app/views/apples_index.erb\nCODE>./db/create_apples.rb\n\nModular application\n\nru.Bee supports modular applications — attach as many subprojects as you need. Each subproject gets its own folder, MVC setup, routes, and namespacing, while still sharing data with the main app.\n\n1. Attach a new subproject\n\nCODE>rubee attach admin\n\n2. Add routes\n\nCODE># admin_routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/admin/cabbages', to: 'cabbages#index',\nCODE> model: {\nCODE> name: 'cabbage',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> },\nCODE> namespace: :admin # mandatory for namespacing support\nCODE>end\n\n3. Run the generate command\n\nCODE>rubee gen get /admin/cabbages app:admin\n\nGenerates:\n\nCODE>./admin/controllers/cabbages_controller.rb\nCODE>./admin/views/cabbages_index.erb\nCODE>./admin/models/cabbage.rb\nCODE>./db/create_cabbages.rb\n\n4. Run the migration\n\nCODE>rubee db run:create_cabbages\n\n5. Fill the controller with content\n\nCODE># ./admin/controllers/cabbages_controller.rb\nCODE>class Admin::CabbagesController < Rubee::BaseController\nCODE> def index\nCODE> response_with object: Cabbage.all, type: :json\nCODE> end\nCODE>end\n\n6. Run the server\n\nCODE>rubee start # or rubee start_dev for development","parent":null,"vector":{"routing":0.02954887726672019,"uses":0.01988100278681613,"explicit":0.01799632189629695,"routes":0.10397299833380914,"define":0.014774438633360094,"any":0.01155255537042324,"main":0.024800043040311356,"http":0.02043070599601113,"method":0.03465766611126972,"include":0.010836032950315336,"match":0.015621904783092532,"parameter":0.016659119523879273,"denot":0.01988100278681613,"route":0.09022830419988637,"path":0.05374894504376969,"a_key":0.01988100278681613,"key":0.06200010760077839,"somewhere":0.01988100278681613,"code":0.5246513181895048,"router":0.24800043040311356,"draw":0.03866927322852273,"post":0.25530748895790595,"index":0.2032690207126457,"create":0.049667789668260964,"patch":0.04997735857163782,"update":0.024800043040311356,"put":0.014774438633360094,"delete":0.03331823904775855,"head":0.01799632189629695,"connect":0.01799632189629695,"option":0.03587100365517277,"trace":0.01799632189629695,"end":0.04367558977727033,"every":0.02954887726672019,"follow":0.01799632189629695,"structure":0.015621904783092532,"http_method":0.01799632189629695,"controller":0.14534651633277657,"acte":0.01405791621325219,"model":0.13767207385828234,"optional":0.04432331590008028,"namespace":0.03331823904775855,"react":0.01405791621325219,"defining":0.0359926437925939,"attributes":0.06718618130471209,"one":0.011180501256367428,"unique":0.05398896568889084,"trait":0.01799632189629695,"generate":0.05960134760191316,"direct":0.01405791621325219,"apples":0.2577951548568182,"name":0.36803692203727745,"apple":0.07387219316680046,"type":0.31424495555914467,"primary":0.05909775453344038,"colour":0.02954887726672019,"string":0.07174200731034554,"weight":0.026874472521884844,"integer":0.04432331590008028,"creat":0.05623166485300876,"datetime":0.10342107043352065,"updat":0.04031170878282726,"other":0.01799632189629695,"support":0.031546021888909495,"attribute":0.03331823904775855,"types":0.01799632189629695,"sequel":0.02811583242650438,"descripte":0.01799632189629695,"text":0.014774438633360094,"quantity":0.01799632189629695,"date":0.01799632189629695,"modifi":0.01799632189629695,"exist":0.015621904783092532,"time":0.013437236260942422,"active":0.01799632189629695,"boolean":0.01799632189629695,"hash":0.016659119523879273,"bigint":0.01799632189629695,"price":0.01799632189629695,"decimal":0.01799632189629695,"item_id":0.01799632189629695,"item":0.05398896568889084,"foreign_key":0.01799632189629695,"foreign":0.016659119523879273,"item_id_index":0.01799632189629695,"item_id_unique":0.01799632189629695,"carry":0.01799632189629695,"bas":0.014774438633360094,"schema":0.016659119523879273,"definite":0.01799632189629695,"size":0.0359926437925939,"fix":0.0359926437925939,"true":0.02310511074084648,"get":0.03331823904775855,"translat":0.01799632189629695,"long":0.01799632189629695,"initial":0.016659119523879273,"files":0.014774438633360094,"on":0.04997735857163782,"defin":0.016659119523879273,"view":0.05107676499002782,"generat":0.013437236260942422,"gen":0.04031170878282726,"without":0.015621904783092532,"generates":0.0666364780955171,"app":0.09933557933652193,"apples_controller":0.04997735857163782,"apples_index":0.04997735857163782,"erb":0.05374894504376969,"create_apples":0.031243809566185065,"full":0.012400021520155678,"modular":0.03331823904775855,"applicat":0.012889757742840912,"applicate":0.016659119523879273,"attach":0.05398896568889084,"many":0.014774438633360094,"subproject":0.04997735857163782,"ne":0.01405791621325219,"each":0.014774438633360094,"own":0.014774438633360094,"folder":0.01799632189629695,"mvc":0.01799632189629695,"setup":0.012400021520155678,"namespacing":0.0359926437925939,"while":0.01799632189629695,"still":0.01799632189629695,"sharing":0.01799632189629695,"data":0.013437236260942422,"new":0.01155255537042324,"admin":0.17184095261401788,"add":0.011180501256367428,"admin_routes":0.01799632189629695,"cabbages":0.1439705751703756,"cabbage":0.05398896568889084,"mandatory":0.016659119523879273,"command":0.01155255537042324,"cabbages_controller":0.0359926437925939,"cabbages_index":0.01799632189629695,"create_cabbages":0.0359926437925939,"migrate":0.013437236260942422,"fill":0.016659119523879273,"content":0.01799632189629695,"clas":0.008951352059796157,"cabbagescontroller":0.01799632189629695,"basecontroller":0.014774438633360094,"def":0.0105153406296365,"response_with":0.012889757742840912,"response":0.011957001218390923,"object":0.011180501256367428,"all":0.010836032950315336,"json":0.0105153406296365,"server":0.010836032950315336,"start":0.018833118984040248,"start_dev":0.01405791621325219,"dev":0.013437236260942422,"development":0.011180501256367428}},{"label":"Routing — Routing methods","body":"CODE>Rubee::Router.draw do |router|\nCODE> router.get '/posts', to: 'posts#index'\nCODE> router.post '/posts', to: 'posts#create'\nCODE> router.patch '/posts/{id}', to: 'posts#update'\nCODE> router.put '/posts/{id}', to: 'posts#update'\nCODE> router.delete '/posts/{id}', to: 'posts#delete'\nCODE> router.head '/posts', to: 'posts#index'\nCODE> router.connect '/posts', to: 'posts#index'\nCODE> router.options '/posts', to: 'posts#index'\nCODE> router.trace '/posts', to: 'posts#index'\nCODE>end\n\nEvery route follows this structure:\n\nCODE>route.{http_method} {path}, to: \"{controller}#{action}\",\nCODE> model: { ...optional }, namespace: { ...optional }, react: { ...optional }","parent":"Routing","vector":{"routing":0.09238760800953026,"method":0.07224050832368722,"code":0.21984425712577763,"router":0.42646938795354933,"draw":0.04030115509751055,"post":0.7982451583128658,"index":0.18692397879670633,"create":0.031058291935437847,"patch":0.052086452912019715,"update":0.07753988871882715,"put":0.04619380400476513,"delete":0.10417290582403943,"head":0.056267353847686656,"connect":0.056267353847686656,"option":0.03738479575934127,"trace":0.056267353847686656,"end":0.027311245916419747,"every":0.04619380400476513,"route":0.0806023101950211,"follow":0.056267353847686656,"structure":0.0488434942023351,"http_method":0.056267353847686656,"http":0.03193935322617668,"path":0.0420129030690982,"controller":0.034956988656442006,"acte":0.043953522863744425,"model":0.028696394516492058,"optional":0.1385814120142954,"namespace":0.052086452912019715,"react":0.043953522863744425}},{"label":"Routing — Defining model attributes in routes","body":"One of ru.Bee's unique traits is defining models for generation directly in the routes:\n\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: \"apple\",\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\nCODE>end\n\nOther supported attribute types via Sequel:\n\nCODE>[\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'description', type: :text },\nCODE> { name: 'quantity', type: :integer },\nCODE> { name: 'created', type: :date },\nCODE> { name: 'modified', type: :datetime },\nCODE> { name: 'exists', type: :time },\nCODE> { name: 'active', type: :boolean },\nCODE> { name: 'hash', type: :bigint },\nCODE> { name: 'price', type: :decimal },\nCODE> { name: 'item_id', type: :foreign_key },\nCODE> { name: 'item_id_index', type: :index },\nCODE> { name: 'item_id_unique', type: :unique }\nCODE>]\n\nEvery attribute can carry options based on the Sequel schema definition. For example:\n\nCODE>{ name: 'key', type: :string, options: { size: 50, fixed: true } }\n\nGets translated to:\n\nCODE>String :key, size: 50, fixed: true","parent":"Routing","vector":{"routing":0.03744956250277125,"defining":0.09123248583585451,"model":0.06979295880928277,"attributes":0.06812016777171076,"routes":0.05856576417523045,"one":0.02833981655771512,"unique":0.1368487287537818,"trait":0.045616242917927256,"generate":0.025179122398006317,"direct":0.03563335467096375,"code":0.4250073962050324,"router":0.09429300005475082,"draw":0.032672360704531084,"apples":0.06534472140906217,"index":0.09092415805148021,"name":0.5597297626202125,"apple":0.03744956250277125,"type":0.5218668108603469,"primary":0.0748991250055425,"colour":0.03744956250277125,"string":0.12123221073530693,"weight":0.03406008388585538,"integer":0.0748991250055425,"creat":0.0712667093419275,"datetime":0.11234868750831374,"updat":0.03406008388585538,"end":0.02214137226867072,"other":0.045616242917927256,"support":0.026653798220010117,"attribute":0.08445352860202278,"types":0.045616242917927256,"sequel":0.0712667093419275,"descripte":0.045616242917927256,"text":0.03744956250277125,"quantity":0.045616242917927256,"date":0.045616242917927256,"modifi":0.045616242917927256,"exist":0.03959768043340628,"time":0.03406008388585538,"active":0.045616242917927256,"boolean":0.045616242917927256,"hash":0.04222676430101139,"bigint":0.045616242917927256,"price":0.045616242917927256,"decimal":0.045616242917927256,"item_id":0.045616242917927256,"item":0.1368487287537818,"foreign_key":0.045616242917927256,"foreign":0.04222676430101139,"key":0.09429300005475082,"item_id_index":0.045616242917927256,"item_id_unique":0.045616242917927256,"every":0.03744956250277125,"carry":0.045616242917927256,"option":0.06061610536765347,"bas":0.03744956250277125,"schema":0.04222676430101139,"definite":0.045616242917927256,"size":0.09123248583585451,"fix":0.09123248583585451,"true":0.05856576417523045,"get":0.04222676430101139,"translat":0.045616242917927256}},{"label":"Routing — Generation from routes","body":"As long as a route has a model: key, you can use it to generate initial model files. If only path and to: are defined, only a controller and view will be generated.\n\nCODE>rubee generate get /apples # or: rubee gen get /apples\nCODE>rubee generate patch /apples/{id} # or: rubee gen patch /apples/{id}\n\nExample 1 — route without a model:\n\nCODE>router.get \"/apples\", to: \"apples#index\"\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\n\nExample 2 — route with a model name only:\n\nCODE>router.get \"/apples\", to: \"apples#index\", model: { name: 'apple' }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/views/apples_index.erb\nCODE>./app/models/apple.rb\nCODE>./db/create_apples.rb\n\nExample 3 — route with full model attributes:\n\nCODE>router.get \"/apples\", to: \"apples#index\",\nCODE> model: {\nCODE> name: 'apple',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'colour', type: :string },\nCODE> { name: 'weight', type: :integer },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> }\n\nGenerates:\n\nCODE>./app/controllers/apples_controller.rb\nCODE>./app/models/apple.rb\nCODE>./app/views/apples_index.erb\nCODE>./db/create_apples.rb","parent":"Routing","vector":{"routing":0.03985032763843845,"generate":0.10717308402571007,"routes":0.031160108887864184,"long":0.04854054638901273,"route":0.13906750218515457,"model":0.22280144996621615,"key":0.03344593541348718,"initial":0.044933779730588264,"files":0.03985032763843845,"on":0.13480133919176476,"path":0.036243560980013995,"defin":0.044933779730588264,"controller":0.2110961062544412,"view":0.11021336891775889,"generat":0.036243560980013995,"code":0.36472031196533233,"apples":0.6258037598331956,"gen":0.07248712196002799,"patch":0.08986755946117653,"without":0.042136154164061454,"router":0.10033780624046154,"index":0.19350599827875278,"generates":0.13480133919176476,"app":0.21434616805142015,"apples_controller":0.13480133919176476,"apples_index":0.13480133919176476,"erb":0.10873068294004197,"name":0.226899866570699,"apple":0.1594013105537538,"create_apples":0.08427230832812291,"create":0.05358654201285504,"full":0.03344593541348718,"attributes":0.07248712196002799,"type":0.14613735048990284,"primary":0.03985032763843845,"colour":0.03985032763843845,"string":0.032250999713125464,"weight":0.036243560980013995,"integer":0.03985032763843845,"creat":0.037917688848554836,"datetime":0.0797006552768769,"updat":0.036243560980013995}},{"label":"Routing — Modular application","body":"ru.Bee supports modular applications — attach as many subprojects as you need. Each subproject gets its own folder, MVC setup, routes, and namespacing, while still sharing data with the main app.\n\n1. Attach a new subproject\n\nCODE>rubee attach admin\n\n2. Add routes\n\nCODE># admin_routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get '/admin/cabbages', to: 'cabbages#index',\nCODE> model: {\nCODE> name: 'cabbage',\nCODE> attributes: [\nCODE> { name: 'id', type: :primary },\nCODE> { name: 'name', type: :string },\nCODE> { name: 'created', type: :datetime },\nCODE> { name: 'updated', type: :datetime },\nCODE> ]\nCODE> },\nCODE> namespace: :admin # mandatory for namespacing support\nCODE>end\n\n3. Run the generate command\n\nCODE>rubee gen get /admin/cabbages app:admin\n\nGenerates:\n\nCODE>./admin/controllers/cabbages_controller.rb\nCODE>./admin/views/cabbages_index.erb\nCODE>./admin/models/cabbage.rb\nCODE>./db/create_cabbages.rb\n\n4. Run the migration\n\nCODE>rubee db run:create_cabbages\n\n5. Fill the controller with content\n\nCODE># ./admin/controllers/cabbages_controller.rb\nCODE>class Admin::CabbagesController < Rubee::BaseController\nCODE> def index\nCODE> response_with object: Cabbage.all, type: :json\nCODE> end\nCODE>end\n\n6. Run the server\n\nCODE>rubee start # or rubee start_dev for development","parent":"Routing","vector":{"routing":0.043732787922028886,"modular":0.09862300141279234,"applicat":0.0381540751376616,"support":0.0622514564641975,"applicate":0.04931150070639617,"attach":0.1598089812543344,"many":0.043732787922028886,"subproject":0.1479345021191885,"ne":0.04161185975564811,"each":0.043732787922028886,"get":0.04931150070639617,"own":0.043732787922028886,"folder":0.05326966041811148,"mvc":0.05326966041811148,"setup":0.03670444101646603,"routes":0.10258774627783888,"namespacing":0.10653932083622296,"while":0.05326966041811148,"still":0.05326966041811148,"sharing":0.05326966041811148,"data":0.039774628210313585,"main":0.03670444101646603,"app":0.05880726749816279,"new":0.0341959154259463,"code":0.44828400264616847,"admin":0.5086544486380348,"add":0.033094623927209965,"admin_routes":0.05326966041811148,"router":0.1101133230493981,"draw":0.0381540751376616,"cabbages":0.42615728334489184,"index":0.1061792623281025,"model":0.05433513704076689,"name":0.1867543693925925,"cabbage":0.1598089812543344,"attributes":0.039774628210313585,"type":0.16037493629782756,"primary":0.043732787922028886,"string":0.035393087442700845,"creat":0.04161185975564811,"datetime":0.08746557584405777,"updat":0.039774628210313585,"namespace":0.04931150070639617,"mandatory":0.04931150070639617,"end":0.07756864483985475,"generate":0.029403633749081396,"command":0.0341959154259463,"gen":0.039774628210313585,"generates":0.04931150070639617,"controller":0.16547311963604977,"cabbages_controller":0.10653932083622296,"view":0.030237755714231,"cabbages_index":0.05326966041811148,"erb":0.039774628210313585,"create_cabbages":0.10653932083622296,"create":0.05880726749816279,"migrate":0.039774628210313585,"fill":0.04931150070639617,"content":0.05326966041811148,"clas":0.026496274475198235,"cabbagescontroller":0.05326966041811148,"basecontroller":0.043732787922028886,"def":0.03112572823209875,"response_with":0.0381540751376616,"response":0.035393087442700845,"object":0.033094623927209965,"all":0.032074987259565514,"json":0.03112572823209875,"server":0.032074987259565514,"start":0.05574660526049744,"start_dev":0.04161185975564811,"dev":0.039774628210313585,"development":0.033094623927209965}},{"label":"Views","body":"A view in ru.Bee is a plain HTML, ERB, or React file rendered from the controller.\n\nTemplates with ERB\n\nlayout.erb is the parent template rendered first; child templates are rendered inside it. Feel free to include custom CSS and JS files there.\n\nCODE># app/controllers/welcome_controller.rb\nCODE>\nCODE>class WelcomeController\nCODE>\nCODE>All set up and running!\n\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\n\nReact as a view\n\nReact is supported out of the box as a view layer in ru.Bee.\n\nPrerequisites: Node and NPM are required.\n\n1. After creating your project and bundling, install React dependencies:\n\nCODE>rubee react prepare\n\n2. Configure React in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE>\nCODE> # register React as a view\nCODE> config.react = { on: true, env: }\nCODE>end\n\n3. Start the server:\n\nCODE>rubee start\nCODE># Default port is 7000. To change it:\nCODE>rubee start --port=3000\n\n4. Open your browser and navigate to http://localhost:3000/home.\n\n5. For development, run rubee start_dev in one terminal and rubee react watch in another. Changes apply instantly.\n\n6. In production, rebuild the React app with rubee react build. Not needed in development when using rubee react watch.\n\n7. Generate a React view from a route by specifying the view name:\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get('/', to: 'welcome#show')\nCODE>\nCODE> router.get('/api/users', to: 'user#index', react: { view_name: 'users.tsx' })\nCODE> # Note: /api/users is the backend endpoint.\nCODE> # To render /app/views/users.tsx, update the React routes as shown below.\nCODE>end\n\n8. Add logic to the generated API controller:\n\nCODE># app/controllers/api/user_controller.rb\nCODE>class Api::UserController\nCODE>\nCODE> } />\nCODE> } />\nCODE>\nCODE>\n\n10. Fetch data from the backend in the component:\n\nCODE>// app/views/users.tsx\nCODE>import { useState, useEffect } from 'react';\nCODE>\nCODE>function Users() {\nCODE> const [users, setUsers] = useState([]);\nCODE>\nCODE> useEffect(() => {\nCODE> fetch('/api/users')\nCODE> .then(response => response.json())\nCODE> .then(data => setUsers(data));\nCODE> }, []);\nCODE>\nCODE> return (\nCODE>\nCODE> Users\nCODE>\nCODE> {users.map(user => (\nCODE> id: {user.id}: {user.name}\nCODE> ))}\nCODE>\nCODE>\nCODE> );\nCODE>}","parent":null,"vector":{"view":0.20131679238614844,"plain":0.03546585027084677,"html":0.03546585027084677,"erb":0.07944340160685352,"react":0.4432692008176643,"file":0.022766941010174107,"render":0.11081730020441607,"controller":0.13220234194397246,"templates":0.07093170054169354,"layout":0.03546585027084677,"parent":0.03546585027084677,"template":0.03546585027084677,"first":0.022766941010174107,"child":0.03546585027084677,"inside":0.032830588499287494,"feel":0.03078652066656958,"free":0.03078652066656958,"include":0.021354870420767686,"custom":0.029116395640510433,"cs":0.03546585027084677,"files":0.029116395640510433,"there":0.032830588499287494,"code":0.6288943156122253,"app":0.11745802737753303,"welcome_controller":0.032830588499287494,"welcome":0.05540865010220804,"clas":0.035281355123981256,"welcomecontroller":0.032830588499287494,"all":0.021354870420767686,"running":0.023563993650671668,"support":0.02072287317745619,"box":0.032830588499287494,"layer":0.03546585027084677,"prerequisites":0.032830588499287494,"node":0.03546585027084677,"npm":0.03546585027084677,"requir":0.025402202781733368,"after":0.026481133868951172,"creating":0.03546585027084677,"project":0.03078652066656958,"bundling":0.03546585027084677,"install":0.024437066036233253,"dependency":0.029116395640510433,"prepare":0.032830588499287494,"configure":0.025402202781733368,"config":0.10677435210383844,"base_configurate":0.025402202781733368,"base":0.02072287317745619,"configurate":0.047127987301343335,"setup":0.024437066036233253,"env":0.06610117097198623,"development":0.08813489462931495,"database_url":0.029116395640510433,"database":0.022033723657328738,"url":0.047127987301343335,"sqlite":0.02770432505110402,"register":0.032830588499287494,"true":0.022766941010174107,"end":0.034429078040670684,"start":0.07422989896157078,"server":0.021354870420767686,"default":0.02072287317745619,"port":0.06566117699857499,"7000":0.032830588499287494,"change":0.03546585027084677,"3000":0.07093170054169354,"open":0.029116395640510433,"browser":0.032830588499287494,"navigate":0.03546585027084677,"http":0.020131679238614846,"localhost":0.026481133868951172,"home":0.03546585027084677,"start_dev":0.02770432505110402,"dev":0.026481133868951172,"one":0.022033723657328738,"terminal":0.032830588499287494,"watch":0.058232791281020865,"another":0.03546585027084677,"changes":0.03078652066656958,"instant":0.03546585027084677,"producte":0.026481133868951172,"rebuild":0.03546585027084677,"build":0.026481133868951172,"not":0.022766941010174107,"need":0.02770432505110402,"generate":0.019576337896255503,"route":0.025402202781733368,"specifying":0.03546585027084677,"name":0.06216861953236858,"routes":0.045533882020348214,"router":0.09774826414493301,"draw":0.025402202781733368,"api":0.1847191239994175,"user":0.29364506844383254,"index":0.023563993650671668,"view_name":0.03546585027084677,"tsx":0.1063975508125403,"backend":0.07093170054169354,"endpoint":0.03078652066656958,"update":0.024437066036233253,"shown":0.03546585027084677,"below":0.03546585027084677,"add":0.022033723657328738,"logic":0.029116395640510433,"generat":0.026481133868951172,"user_controller":0.03546585027084677,"usercontroller":0.03546585027084677,"fetch":0.058232791281020865,"data":0.07944340160685352,"component":0.03546585027084677,"import":0.03546585027084677,"usestate":0.07093170054169354,"useeffect":0.07093170054169354,"functe":0.03546585027084677,"const":0.03078652066656958,"setuser":0.07093170054169354,"then":0.052962267737902344,"response":0.047127987301343335,"json":0.02072287317745619,"return":0.03078652066656958,"map":0.03546585027084677}},{"label":"Views — Templates with ERB","body":"layout.erb is the parent template rendered first; child templates are rendered inside it. Feel free to include custom CSS and JS files there.\n\nCODE># app/controllers/welcome_controller.rb\nCODE>\nCODE>class WelcomeController\nCODE>\nCODE>All set up and running!\n\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>\nCODE>","parent":"Views","vector":{"view":0.09528264364344313,"templates":0.3357176450921154,"erb":0.25066885000530087,"layout":0.1678588225460577,"parent":0.1678588225460577,"template":0.1678588225460577,"render":0.26224750552980547,"first":0.10775525982764309,"child":0.1678588225460577,"inside":0.15538620636185774,"feel":0.14571169364091657,"free":0.14571169364091657,"include":0.10107197140569545,"custom":0.1378070411868504,"cs":0.1678588225460577,"files":0.1378070411868504,"there":0.15538620636185774,"code":0.5549478062973604,"app":0.09265422946113287,"controller":0.20856992747553907,"welcome_controller":0.15538620636185774,"welcome":0.13112375276490273,"clas":0.08349280623068812,"welcomecontroller":0.15538620636185774,"all":0.10107197140569545,"running":0.11152768644985564}},{"label":"Views — React as a view","body":"React is supported out of the box as a view layer in ru.Bee.\n\nPrerequisites: Node and NPM are required.\n\n1. After creating your project and bundling, install React dependencies:\n\nCODE>rubee react prepare\n\n2. Configure React in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: 'sqlite://db/development.db', env: }\nCODE>\nCODE> # register React as a view\nCODE> config.react = { on: true, env: }\nCODE>end\n\n3. Start the server:\n\nCODE>rubee start\nCODE># Default port is 7000. To change it:\nCODE>rubee start --port=3000\n\n4. Open your browser and navigate to http://localhost:3000/home.\n\n5. For development, run rubee start_dev in one terminal and rubee react watch in another. Changes apply instantly.\n\n6. In production, rebuild the React app with rubee react build. Not needed in development when using rubee react watch.\n\n7. Generate a React view from a route by specifying the view name:\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> router.get('/', to: 'welcome#show')\nCODE>\nCODE> router.get('/api/users', to: 'user#index', react: { view_name: 'users.tsx' })\nCODE> # Note: /api/users is the backend endpoint.\nCODE> # To render /app/views/users.tsx, update the React routes as shown below.\nCODE>end\n\n8. Add logic to the generated API controller:\n\nCODE># app/controllers/api/user_controller.rb\nCODE>class Api::UserController\nCODE>\nCODE> } />\nCODE> } />\nCODE>\nCODE>\n\n10. Fetch data from the backend in the component:\n\nCODE>// app/views/users.tsx\nCODE>import { useState, useEffect } from 'react';\nCODE>\nCODE>function Users() {\nCODE> const [users, setUsers] = useState([]);\nCODE>\nCODE> useEffect(() => {\nCODE> fetch('/api/users')\nCODE> .then(response => response.json())\nCODE> .then(data => setUsers(data));\nCODE> }, []);\nCODE>\nCODE> return (\nCODE>\nCODE> Users\nCODE>\nCODE> {users.map(user => (\nCODE> id: {user.id}: {user.name}\nCODE> ))}\nCODE>\nCODE>\nCODE> );\nCODE>}","parent":"Views","vector":{"view":0.20619195363123938,"react":0.4729203857110419,"support":0.023583006523459883,"box":0.037361806739714135,"layer":0.04036078255824662,"prerequisites":0.037361806739714135,"node":0.04036078255824662,"npm":0.04036078255824662,"requir":0.02890816870720268,"after":0.030136011904925923,"creating":0.04036078255824662,"project":0.03503562037450382,"bundling":0.04036078255824662,"install":0.027809825539715605,"dependency":0.03313498772345841,"code":0.5822588482759652,"prepare":0.037361806739714135,"configure":0.02890816870720268,"config":0.12151115439640621,"base_configurate":0.02890816870720268,"base":0.023583006523459883,"configurate":0.053632506576076294,"setup":0.027809825539715605,"env":0.07522433462250452,"development":0.10029911283000603,"database_url":0.03313498772345841,"database":0.025074778207501508,"url":0.053632506576076294,"sqlite":0.03152802571406946,"register":0.037361806739714135,"true":0.025909192888670194,"end":0.03918091690649987,"start":0.08447497489638064,"server":0.024302230879281243,"default":0.023583006523459883,"port":0.07472361347942827,"7000":0.037361806739714135,"change":0.04036078255824662,"3000":0.08072156511649324,"open":0.03313498772345841,"browser":0.037361806739714135,"navigate":0.04036078255824662,"http":0.022910217070137708,"localhost":0.030136011904925923,"home":0.04036078255824662,"start_dev":0.03152802571406946,"dev":0.030136011904925923,"one":0.025074778207501508,"terminal":0.037361806739714135,"watch":0.06626997544691682,"another":0.04036078255824662,"changes":0.03503562037450382,"app":0.11139114261797552,"instant":0.04036078255824662,"producte":0.030136011904925923,"rebuild":0.04036078255824662,"build":0.030136011904925923,"not":0.025909192888670194,"need":0.03152802571406946,"generate":0.022278228523595105,"route":0.02890816870720268,"specifying":0.04036078255824662,"name":0.07074901957037964,"routes":0.05181838577734039,"router":0.11123930215886242,"draw":0.02890816870720268,"welcome":0.03152802571406946,"api":0.21021372224702292,"user":0.33417342785392656,"index":0.026816253288038147,"view_name":0.04036078255824662,"tsx":0.12108234767473987,"backend":0.08072156511649324,"endpoint":0.03503562037450382,"render":0.03152802571406946,"update":0.027809825539715605,"shown":0.04036078255824662,"below":0.04036078255824662,"add":0.025074778207501508,"logic":0.03313498772345841,"generat":0.030136011904925923,"controller":0.07522433462250452,"user_controller":0.04036078255824662,"clas":0.02007541186302552,"usercontroller":0.04036078255824662,"fetch":0.06626997544691682,"data":0.09040803571477776,"component":0.04036078255824662,"import":0.04036078255824662,"usestate":0.08072156511649324,"useeffect":0.08072156511649324,"functe":0.04036078255824662,"const":0.03503562037450382,"setuser":0.08072156511649324,"then":0.060272023809851846,"response":0.053632506576076294,"json":0.023583006523459883,"return":0.03503562037450382,"map":0.04036078255824662}},{"label":"Object hooks","body":"By including the Hookable module, any Ruby object can be charged with hooks — logic that executes before, after, or around a specific method call.\n\nBaseController is Hookable by default:\n\nCODE>class ApplesController { puts \"after index\" }, if: -> { true } # or use a lambda\nCODE> after :index, -> { puts \"after index2\" }, unless: -> { false } # if/unless guards accept a method or lambda\nCODE> around :index, :log\nCODE>\nCODE> def index\nCODE> response_with object: { test: \"hooks\" }\nCODE> end\nCODE>\nCODE> def print_hello\nCODE> puts \"hello!\"\nCODE> end\nCODE>\nCODE> def log\nCODE> puts \"before log around\"\nCODE> res = yield\nCODE> puts \"after log around\"\nCODE> res\nCODE> end\nCODE>end\n\nThe server logs will show the following execution stack:\n\nCODE>before log around\nCODE>hello!\nCODE>after index\nCODE>after index2\nCODE>after log around\nCODE>127.0.0.1 - - [17/Feb/2025:11:42:14 -0500] \"GET /apples HTTP/1.1\" 401 - 0.0359\n\nStarting from version 1.11, hooks can also be pinned to class methods:\n\nCODE>class AnyClass\nCODE> include Rubee::Hookable\nCODE> before :print_world, :print_hello, class_methods: true\nCODE>\nCODE> class << self\nCODE> def print_world\nCODE> puts \"world!\"\nCODE> end\nCODE>\nCODE> def print_hello\nCODE> puts \"hello!\"\nCODE> end\nCODE> end\nCODE>end\n\nOutput:\n\nCODE>hello!\nCODE>world!","parent":null,"vector":{"object":0.08206487189376384,"hook":0.13758012772182682,"including":0.044030996974530515,"hookable":0.14592654742473654,"module":0.038221590289640665,"any":0.02826524961569339,"ruby":0.02826524961569339,"charg":0.040759308795493616,"logic":0.03614812329511195,"executes":0.04864218247491218,"before":0.11701917480810574,"after":0.26301148092860044,"around":0.26418598184718306,"specific":0.029254793702026435,"method":0.11306099846277357,"call":0.034395031930456704,"basecontroller":0.03614812329511195,"default":0.025727531109840444,"code":0.542572349131649,"clas":0.10950486375328239,"applescontroller":0.044030996974530515,"put":0.25303686306578366,"index":0.14627396851013216,"true":0.05653049923138678,"lambda":0.09728436494982436,"index2":0.09728436494982436,"unles":0.0722962465902239,"false":0.034395031930456704,"guard":0.044030996974530515,"accept":0.04864218247491218,"log":0.26755113202748465,"def":0.1286376555492022,"response_with":0.03153693779473029,"response":0.029254793702026435,"test":0.024993561436656493,"end":0.17097536018086298,"print_hello":0.14592654742473654,"print":0.20379654397746805,"hello":0.26755113202748465,"res":0.09728436494982436,"yield":0.04864218247491218,"server":0.026512158251038143,"execute":0.044030996974530515,"stack":0.044030996974530515,"127":0.044030996974530515,"feb":0.04864218247491218,"2025":0.044030996974530515,"0500":0.04864218247491218,"apples":0.03153693779473029,"http":0.024993561436656493,"401":0.04864218247491218,"0359":0.04864218247491218,"starting":0.034395031930456704,"version":0.032876435116075055,"pinn":0.04864218247491218,"anyclas":0.04864218247491218,"include":0.026512158251038143,"print_world":0.09728436494982436,"world":0.1945687298996487,"class_method":0.04864218247491218,"self":0.04864218247491218,"output":0.03614812329511195}},{"label":"Validations","body":"Any class can be charged with validations by including the Validatable module.\nru.Bee models are validatable by default — no need to include it explicitly.\n\nCODE>class Foo\nCODE> include Rubee::Validatable\nCODE>\nCODE> attr_accessor :name, :age\nCODE>\nCODE> def initialize(name, age)\nCODE> @name = name\nCODE> @age = age\nCODE> end\nCODE>\nCODE> validate do\nCODE> attribute(:name).required.type(String).condition(->{ name.length > 2 })\nCODE>\nCODE> attribute(:age)\nCODE> .required('Age is a mandatory field')\nCODE> .type(Integer, error_message: 'Must be an integer!')\nCODE> .condition(->{ age > 18 }, fancy_error: 'You must be at least 18 years old!')\nCODE> end\nCODE>end\n\nCODE>irb(main):041> Foo.new(\"Test\", 20).valid?\nCODE>=> true\nCODE>irb(main):042> Foo.new(\"Test\", 1).errors\nCODE>=> {age: {fancy_error: \"You must be at least 18 years old!\"}}\nCODE>irb(main):046> Foo.new(\"Joe\", \"wrong\").valid?\nCODE>=> false\nCODE>irb(main):047> Foo.new(\"Joe\", \"wrong\").errors\nCODE>=> {age: {error_message: \"Must be an integer!\"}}\n\nModel example with persistence guards:\n\nCODE>class User { email.match?(/\\A[\\w+\\-.]+@[a-z\\d\\-]+(\\.[a-z\\d\\-]+)*\\.[a-z]+\\z/i) }, error: 'Wrong email format'\nCODE> )\nCODE> end\nCODE>end\n\nCODE>irb(main):077> user.save\nCODE>=> {email: {error: \"Wrong email format\"}} (Rubee::Validatable::Error)\nCODE>irb(main):078> user.email = \"ok@ok.com\"\nCODE>irb(main):080> user.save\nCODE>=> true\n\nTo apply validate_before_persist! and validate_after_setters globally, add an initializer such as init/sequel_object_preloader.rb:\n\nCODE>Rubee::SequelObject.validate_before_persist!\nCODE>Rubee::SequelObject.validate_after_setters","parent":null,"vector":{"validate":0.3115827053243501,"any":0.025865154463025106,"clas":0.060123867730329676,"charg":0.03729830205413234,"including":0.04029218044743189,"validatable":0.17804726018534292,"module":0.034976069559107065,"model":0.04109808714940057,"default":0.02354292196799983,"ne":0.03147443683455046,"include":0.048521847684694135,"explicit":0.04029218044743189,"code":0.46017142632191876,"foo":0.22255907523167867,"attr_accessor":0.04029218044743189,"attr":0.04029218044743189,"accessor":0.04029218044743189,"name":0.141257531807999,"age":0.335684718487191,"def":0.02354292196799983,"initialize":0.030084789061928956,"end":0.09778580059828192,"attribute":0.07459660410826469,"requir":0.0577180657126493,"type":0.048521847684694135,"string":0.026770673111859773,"condite":0.08902363009267146,"length":0.04451181504633573,"mandatory":0.03729830205413234,"field":0.03729830205413234,"integer":0.0992360023656855,"error_message":0.08902363009267146,"error":0.24986300910213308,"message":0.07459660410826469,"must":0.16116872178972755,"fancy_error":0.08902363009267146,"fancy":0.08902363009267146,"least":0.07459660410826469,"year":0.08902363009267146,"old":0.08902363009267146,"irb":0.2610881143789264,"main":0.1943378959683257,"041":0.04451181504633573,"new":0.10346061785210042,"test":0.04574255213945113,"valid":0.08902363009267146,"true":0.05173030892605021,"042":0.04451181504633573,"046":0.04451181504633573,"joe":0.08902363009267146,"wrong":0.14919320821652937,"false":0.03147443683455046,"047":0.04451181504633573,"persistence":0.03729830205413234,"guard":0.04029218044743189,"user":0.08896144691212486,"email":0.12932577231512554,"match":0.034976069559107065,"format":0.08902363009267146,"077":0.04451181504633573,"save":0.07459660410826469,"078":0.04451181504633573,"com":0.025865154463025106,"080":0.04451181504633573,"app":0.022240361728031215,"validate_before_persist":0.08902363009267146,"before":0.053541346223719546,"persist":0.07459660410826469,"validate_after_setter":0.08902363009267146,"after":0.06016957812385791,"setter":0.08902363009267146,"global":0.04029218044743189,"add":0.025032158054862905,"initializer":0.04451181504633573,"such":0.04451181504633573,"init":0.030084789061928956,"sequel_object_preloader":0.04451181504633573,"sequel":0.03147443683455046,"object":0.025032158054862905,"preloader":0.04451181504633573,"sequelobject":0.07459660410826469}},{"label":"Rubee support","body":"An optional set of useful methods can be added to base Ruby classes globally via configuration:\n\nCODE># Include all support methods\nCODE>Rubee::Configuration.setup do |config|\nCODE> config.rubee_support = { all: true }\nCODE>end\nCODE>\nCODE># Include only methods for a specific class\nCODE>Rubee::Configuration.setup do |config|\nCODE> config.rubee_support = { classes: [Rubee::Support::String] }\nCODE>end\n\nAvailable extensions:\n\nCODE># Hash — tolerates string or symbol keys interchangeably\nCODE>{one: 1}[:one] # => 1\nCODE>{one: 1}[\"one\"] # => 1\nCODE>\nCODE># Hash — deep digging\nCODE>{one: {two: 2}}.deep_dig(:two) # => 2\n\nCODE># String — enriched with helper methods\nCODE>\"test\".pluralize # => \"tests\"\nCODE>\"test\".singularize # => \"test\"\nCODE>\"test\".camelize # => \"Test\"\nCODE>\"TestMe\".snakeize # => \"test_me\"\nCODE>\"test\".singular? # => true\nCODE>\"test\".plural? # => false","parent":null,"vector":{"support":0.2271874681508323,"optional":0.06384134237178685,"useful":0.08590714930729798,"method":0.19967747295843785,"add":0.04831169740583329,"base":0.045437493630166456,"ruby":0.04991936823960946,"classes":0.17181429861459596,"global":0.07776331650396424,"configurate":0.15500101779831107,"code":0.5141771072824173,"include":0.09364645340514227,"all":0.09364645340514227,"setup":0.10716265286700037,"config":0.18729290681028454,"rubee_support":0.17181429861459596,"true":0.09983873647921893,"end":0.07549006360118593,"on":0.07198517517512058,"specific":0.05166700593277035,"clas":0.038679393899237406,"string":0.15500101779831107,"available":0.05569750956845312,"extension":0.08590714930729798,"hash":0.14397035035024117,"tolerates":0.08590714930729798,"symbol":0.08590714930729798,"key":0.053581326433500186,"interchangeab":0.08590714930729798,"one":0.24155848702916646,"deep":0.17181429861459596,"digging":0.08590714930729798,"two":0.1555266330079285,"deep_dig":0.08590714930729798,"dig":0.08590714930729798,"enrich":0.08590714930729798,"helper":0.07198517517512058,"test":0.39727104219689224,"pluralize":0.08590714930729798,"singularize":0.08590714930729798,"camelize":0.08590714930729798,"testme":0.08590714930729798,"snakeize":0.08590714930729798,"test_me":0.08590714930729798,"singular":0.08590714930729798,"plural":0.08590714930729798,"false":0.060745200834748526}},{"label":"JWT based authentication","body":"Include the AuthTokenable module in your controller and authenticate any action you need.\n\nFirst, initialize the User model:\n\nCODE>rubee db run:create_users\n\nThis creates the users table and seeds it with demo credentials — email ok@ok.com, password password. Customize /db/create_users.rb before running the migration if needed.\n\nCODE>class UsersController < Rubee::BaseController\nCODE> include Rubee::AuthTokenable\nCODE> auth_methods :index # unauthenticated requests to these actions will be rejected\nCODE>\nCODE> # GET /users/login\nCODE> def edit\nCODE> response_with\nCODE> end\nCODE>\nCODE> # POST /users/login\nCODE> def login\nCODE> if authenticate! # initializes @token_header\nCODE> response_with type: :redirect, to: \"/users\", headers: @token_header\nCODE> else\nCODE> @error = \"Wrong email or password\"\nCODE> response_with render_view: \"users_edit\"\nCODE> end\nCODE> end\nCODE>\nCODE> # POST /users/logout\nCODE> def logout\nCODE> unauthenticate!\nCODE> response_with type: :redirect, to: \"/users/login\", headers: @zeroed_token_header\nCODE> end\nCODE>\nCODE> # GET /users (restricted)\nCODE> def index\nCODE> response_with object: User.all, type: :json\nCODE> end\nCODE>end\n\nSet a JWT_KEY at startup for security:\n\nCODE>JWT_KEY=SDJwer0wer23j rubee start\n\nTo use a custom model instead of the default User, pass arguments to authenticate! and unauthenticate!:\n\nCODE>if authenticate! user_model: Client, login: :name, password: :digest_password\nCODE> response_with type: :redirect, to: \"/clients\", headers: @token_header\nCODE>end","parent":null,"vector":{"jwt":0.12312072677378615,"bas":0.038813867396903075,"authenticat":0.03386262992620047,"include":0.05693459582177831,"authtokenable":0.09455612751846319,"module":0.04104024225792872,"controller":0.029372249190956913,"authenticate":0.18911225503692639,"any":0.03034967103457455,"acte":0.03693149427321767,"ne":0.03693149427321767,"first":0.03034967103457455,"initialize":0.03530090850527716,"user":0.3653497327227803,"model":0.07233554859981502,"code":0.49732811071532623,"create_user":0.10445860245986839,"create":0.05219281896039719,"creates":0.052229301229934195,"table":0.043765104867605674,"seed":0.052229301229934195,"demo":0.047278063759231596,"credential":0.043765104867605674,"email":0.0606993420691491,"com":0.03034967103457455,"password":0.15174835517287277,"customize":0.052229301229934195,"before":0.03141218907006864,"running":0.03141218907006864,"migrate":0.03530090850527716,"need":0.03693149427321767,"clas":0.023516060440186552,"userscontroller":0.047278063759231596,"basecontroller":0.038813867396903075,"auth_method":0.052229301229934195,"auth":0.038813867396903075,"method":0.03034967103457455,"index":0.06282437814013728,"unauthenticat":0.052229301229934195,"request":0.047278063759231596,"action":0.052229301229934195,"reject":0.052229301229934195,"login":0.20520121128964358,"def":0.11049923369959036,"edit":0.09455612751846319,"response_with":0.20317577955720278,"response":0.18847313442041186,"end":0.16063594895418085,"post":0.07060181701055432,"initializes":0.052229301229934195,"token_header":0.14183419127769478,"token":0.18911225503692639,"header":0.33094644631462117,"type":0.11386919164355662,"redirect":0.14183419127769478,"else":0.038813867396903075,"error":0.03257604589560019,"wrong":0.043765104867605674,"render_view":0.047278063759231596,"render":0.03693149427321767,"view":0.026836712142948638,"users_edit":0.047278063759231596,"logout":0.09455612751846319,"unauthenticate":0.09455612751846319,"zeroed_token_header":0.047278063759231596,"zero":0.047278063759231596,"restrict":0.052229301229934195,"object":0.029372249190956913,"all":0.028467297910889155,"json":0.02762480842489759,"jwt_key":0.10445860245986839,"key":0.06515209179120038,"startup":0.052229301229934195,"security":0.052229301229934195,"sdjwer0wer23j":0.052229301229934195,"start":0.02473820498553828,"custom":0.038813867396903075,"instead":0.043765104867605674,"default":0.02762480842489759,"pas":0.03530090850527716,"argument":0.038813867396903075,"user_model":0.052229301229934195,"client":0.07386298854643535,"name":0.02762480842489759,"digest_password":0.052229301229934195,"digest":0.052229301229934195}},{"label":"OAuth authentication","body":"To plug in OAuth 2.0 authentication, add the oauth2 gem to your Gemfile:\n\nCODE>gem 'oauth2'\n\nUse the following as a starting point:\n\nCODE>class UsersController < Rubee::BaseController\nCODE> include Rubee::AuthTokenable\nCODE>\nCODE> REDIRECT_URI = 'https://mysite.com/users/oauth_callback'\nCODE> CLIENT_ID = ENV['GOOGLE_CLIENT_ID']\nCODE> CLIENT_SECRET = ENV['GOOGLE_CLIENT_SECRET']\nCODE>\nCODE> # GET /login\nCODE> def edit\nCODE> response_with\nCODE> end\nCODE>\nCODE> # POST /users/login\nCODE> def login\nCODE> if authenticate!\nCODE> response_with(type: :redirect, to: \"/sections\", headers: @token_header)\nCODE> else\nCODE> @error = \"Wrong email or password\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE> end\nCODE>\nCODE> # GET /users/oauth_login\nCODE> def oauth_login\nCODE> response_with(\nCODE> type: :redirect,\nCODE> to: auth_client.auth_code.authorize_url(\nCODE> redirect_uri: REDIRECT_URI,\nCODE> scope: 'email profile openid'\nCODE> )\nCODE> )\nCODE> end\nCODE>\nCODE> # GET /users/oauth_callback\nCODE> def oauth_callback\nCODE> code = params[:code]\nCODE> token = auth_client.auth_code.get_token(code, redirect_uri: REDIRECT_URI)\nCODE> user_info = JSON.parse(token.get('https://www.googleapis.com/oauth2/v1/userinfo?alt=json').body)\nCODE>\nCODE> user = User.where(email: user_info['email'])&.last\nCODE> raise \"User with email #{user_info['email']} not found\" unless user\nCODE>\nCODE> params[:email] = user_info['email']\nCODE> params[:password] = user.password\nCODE>\nCODE> if authenticate!\nCODE> response_with(type: :redirect, to: \"/sections\", headers: @token_header)\nCODE> else\nCODE> @error = \"Something went wrong\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE> rescue OAuth2::Error\nCODE> @error = \"OAuth login failed\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> rescue StandardError\nCODE> @error = \"Something went wrong\"\nCODE> response_with(render_view: \"users_edit\")\nCODE> end\nCODE>\nCODE> # POST /users/logout\nCODE> def logout\nCODE> unauthenticate!\nCODE> response_with(type: :redirect, to: \"/login\", headers: @zeroed_token_header)\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def auth_client\nCODE> @client ||= OAuth2::Client.new(\nCODE> CLIENT_ID,\nCODE> CLIENT_SECRET,\nCODE> site: 'https://accounts.google.com',\nCODE> authorize_url: '/o/oauth2/auth',\nCODE> token_url: 'https://oauth2.googleapis.com/token'\nCODE> )\nCODE> end\nCODE>end","parent":null,"vector":{"oauth":0.2153644297490162,"authenticat":0.03490763715061156,"plug":0.024368536916469695,"add":0.015139341204298376,"oauth2":0.18844387603038915,"gem":0.036390301281227715,"gemfile":0.02115337598460588,"code":0.6078869620890791,"starting":0.019035603618635186,"point":0.026920553718627026,"clas":0.012120885277471277,"userscontroller":0.024368536916469695,"basecontroller":0.020005835377463112,"include":0.014672902079628604,"authtokenable":0.024368536916469695,"redirect_uri":0.1346027685931351,"redirect":0.21931683224822723,"uri":0.1346027685931351,"http":0.055329796406429085,"mysite":0.026920553718627026,"com":0.0625725353538261,"user":0.24211574693061344,"oauth_callback":0.08076166115588106,"callback":0.08076166115588106,"client_id":0.05384110743725405,"client":0.20939163980498704,"env":0.03027868240859675,"google_client_id":0.026920553718627026,"google":0.08076166115588106,"client_secret":0.05384110743725405,"secret":0.06346012795381764,"google_client_secret":0.026920553718627026,"login":0.14807363189224118,"def":0.08543194586065184,"edit":0.12184268458234845,"response_with":0.157084367177752,"response":0.14571708849824966,"end":0.10645277464719041,"post":0.036390301281227715,"authenticate":0.04873707383293939,"type":0.058691608318514416,"section":0.05384110743725405,"header":0.14621122149881816,"token_header":0.04873707383293939,"token":0.19494829533175756,"else":0.040011670754926225,"error":0.0839533722279965,"wrong":0.06767355653886131,"email":0.1251450707076522,"password":0.046929401515369576,"render_view":0.09747414766587878,"render":0.07614241447454075,"view":0.055329796406429085,"users_edit":0.09747414766587878,"oauth_login":0.05384110743725405,"auth_client":0.08076166115588106,"auth":0.12003501226477867,"auth_code":0.05384110743725405,"authorize_url":0.05384110743725405,"authorize":0.05384110743725405,"url":0.04857236283274989,"scope":0.026920553718627026,"profile":0.026920553718627026,"openid":0.026920553718627026,"param":0.06767355653886131,"get_token":0.026920553718627026,"user_info":0.1076822148745081,"info":0.07614241447454075,"json":0.028477315286883947,"parse":0.02115337598460588,"www":0.026920553718627026,"googleapis":0.05384110743725405,"userinfo":0.026920553718627026,"alt":0.026920553718627026,"body":0.022557852179620436,"last":0.018195150640613857,"raise":0.026920553718627026,"not":0.015643133838456526,"found":0.026920553718627026,"unles":0.020005835377463112,"something":0.04511570435924087,"went":0.05384110743725405,"rescue":0.04230675196921176,"fail":0.02115337598460588,"standarderror":0.024368536916469695,"logout":0.04873707383293939,"unauthenticate":0.024368536916469695,"zeroed_token_header":0.024368536916469695,"zero":0.024368536916469695,"private":0.02115337598460588,"new":0.015643133838456526,"site":0.02115337598460588,"account":0.024368536916469695,"token_url":0.026920553718627026}},{"label":"ru.Bee commands","body":"CODE>rubee start # start the server\nCODE>rubee start_dev # start the server in dev mode, restarting on file changes\nCODE>rubee react prepare # install React dependencies\nCODE>rubee react watch # React dev mode, use together with start_dev\nCODE>rubee stop # stop the server\nCODE>rubee restart # restart the server","parent":null,"vector":{"command":0.08729129901543732,"code":0.2452128258473614,"start":0.3557583945535632,"server":0.32750897514112626,"start_dev":0.21244369377300876,"dev":0.40612791569837053,"mode":0.19479044441500962,"restarting":0.15022118512703828,"file":0.08729129901543732,"changes":0.1180393703286498,"react":0.4248873875460175,"prepare":0.12587658202581545,"install":0.09369476722742699,"dependency":0.11163590211666012,"watch":0.11163590211666012,"together":0.15022118512703828,"stop":0.2517531640516309,"restart":0.30044237025407655}},{"label":"Generate commands","body":"CODE>rubee generate get /apples # generate controller, view, model, and migration if set in routes\nCODE>rubee gen get /apples # shorthand alias","parent":null,"vector":{"generate":0.5200173833142289,"command":0.20159039538654316,"code":0.1887647110841256,"apples":0.44984876098816895,"controller":0.19509810571098601,"view":0.17825641027900185,"model":0.1601571653075155,"migrate":0.23447780026926954,"routes":0.20159039538654316,"gen":0.23447780026926954,"shorthand":0.34692058024980493,"alias":0.29069919025953717}},{"label":"Migration commands","body":"CODE>rubee db run:all # run all migrations\nCODE>rubee db run:create_apples # run a specific migration file from /db\nCODE>rubee db structure # generate a migration file for the database structure","parent":null,"vector":{"migrate":0.6858880868305298,"command":0.14742168603627023,"code":0.20706352541358855,"all":0.2765563455458326,"create_apples":0.1993504872625599,"create":0.12676172603917368,"apples":0.16448567075589438,"specific":0.15258280294122914,"file":0.29484337207254047,"structure":0.3987009745251198,"generate":0.12676172603917368,"database":0.14267391872140742}},{"label":"Info commands","body":"CODE>rubee routes # print the routes table\nCODE>rubee version # print the current framework version","parent":null,"vector":{"info":0.23580507899707032,"command":0.19378058528849842,"code":0.18145178060471198,"routes":0.38756117057699685,"print":0.558874435692942,"table":0.279437217846471,"version":0.450787799549817,"current":0.2620391554183011,"framework":0.24782390336006094}},{"label":"ru.Bee console","body":"CODE>rubee console # start the interactive console\nCODE># type 'reload' inside the console to pick up the latest changes\n\nTo run any ru.Bee command in a specific environment, prefix with the env variable:\n\nCODE>RACK_ENV=test rubee console","parent":null,"vector":{"console":0.8000139186273016,"code":0.14426602797915083,"start":0.08372131486210249,"interactive":0.12498696902962518,"type":0.09634165506608461,"reload":0.1388921729002421,"inside":0.14811390425197507,"pick":0.17675921821551568,"latest":0.1600027837254603,"changes":0.1388921729002421,"any":0.10271215579837917,"command":0.10271215579837917,"specific":0.10630802732779149,"environment":0.11024685893670153,"prefix":0.17675921821551568,"env":0.19880854929949812,"variable":0.17675921821551568,"rack_env":0.14811390425197507,"rack":0.11460103527186438,"test":0.09082327632489395}},{"label":"Testing","body":"CODE>rubee test # run all tests\nCODE>rubee test auth_tokenable_test.rb # run a specific test file\nCODE>rubee test models/user_model_test.rb --line=12 # run a specific line","parent":null,"vector":{"testing":0.20572448020969406,"code":0.16790668072395218,"test":0.7399444312470986,"all":0.11212901432301162,"auth_tokenable_test":0.20572448020969406,"auth":0.15288281686945968,"tokenable":0.20572448020969406,"specific":0.24745712144373044,"file":0.11954343923989968,"model":0.18994692999199894,"user_model_test":0.18622219449901967,"user":0.10279039062801476,"line":0.32330444051023893}},{"label":"Background jobs","body":"There are currently two ways to integrate background jobs into your application:\n • Sidekiq\n • ThreadAsync","parent":null,"vector":{"background":0.5007139023481104,"job":0.47355088421220964,"there":0.26697937486832835,"current":0.2503569511740552,"two":0.28840940620634614,"way":0.28840940620634614,"integrate":0.26697937486832835,"applicat":0.20657150934388124,"sidekiq":0.19872298707381392,"threadasync":0.26697937486832835}},{"label":"Sidekiq engine","body":"The Sidekiq adapter allows you to process background jobs using Redis and the Sidekiq gem.\n\n1. Add Sidekiq to your Gemfile\n\nCODE>gem 'sidekiq'\nCODE>gem 'rack-session' # Required for Sidekiq Web UI\n\n2. Configure the adapter for the desired environment\n\nCODE># config/base_configuration.rb\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"sqlite://db/development.db\", env: }\nCODE> config.async_adapter = { async_adapter: Rubee::SidekiqAsync, env: }\nCODE>end\n\n3. Install dependencies\n\nCODE>bundle install\n\n4. Start Redis - Redis must be running before starting Sidekiq\n\nCODE># Start Redis server\nCODE>redis-server\nCODE>\nCODE># Or in background (macOS with Homebrew)\nCODE>brew services start redis\nCODE>\nCODE># Verify Redis is running\nCODE>redis-cli ping\nCODE># Should respond: PONG\n\n5. Add Sidekiq configuration file\n\nCODE># config/sidekiq.yml\nCODE>:concurrency: 5\nCODE>:queues:\nCODE> - default\nCODE> - mailers\nCODE> - critical\nCODE> - low\nCODE>\nCODE># Redis connection\nCODE>:redis:\nCODE> url: redis://localhost:6379/0\nCODE>\nCODE># Optional: Logging\nCODE>:verbose: false\nCODE>:logfile: ./log/sidekiq.log\nCODE>\nCODE># Optional: PID file for daemon mode\nCODE>:pidfile: ./tmp/pids/sidekiq.pid\n\n6. Create Sidekiq boot file\n\nCODE># inits/sidekiq.rb\nCODE>\nCODE># Configure Redis connection\nCODE>Sidekiq.configure_server do |config|\nCODE> config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }\nCODE>end\nCODE>\nCODE>Sidekiq.configure_client do |config|\nCODE> config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }\nCODE>end\nCODE>\nCODE># Load Rubee application context\nCODE>unless Object.const_defined?('Rubee')\nCODE> require 'rubee'\nCODE>\nCODE> # Load environment variables\nCODE> require_relative 'dev.rb' if File.exist?(File.join(dir, 'dev.rb'))\nCODE>\nCODE> # Trigger Rubee autoload\nCODE> Rubee::Autoload.call\nCODE>end\n\n7. Create a Sidekiq worker\n\nCODE># app/workers/test_async_runner.rb\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :default, retry: 3\nCODE>\nCODE> def perform(options)\nCODE> options = parse_options(options)\nCODE>\nCODE> User.create(\nCODE> email: options['email'],\nCODE> password: options['password']\nCODE> )\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def parse_options(options)\nCODE> return options unless options.is_a?(String)\nCODE>\nCODE> begin\nCODE> JSON.parse(options)\nCODE> rescue JSON::ParserError\nCODE> options\nCODE> end\nCODE> end\nCODE>end\n\n8. Use it in your codebase\n\nCODE># Enqueue job to run asynchronously\nCODE>TestAsyncRunner.new.perform_async({\nCODE> \"email\" => \"new@new.com\",\nCODE> \"password\" => \"123\"\nCODE>}.to_json)\nCODE>\nCODE># Schedule job to run in 5 minutes (300 seconds)\nCODE>TestAsyncRunner.perform_in(300, {\nCODE> \"email\" => \"new@new.com\",\nCODE> \"password\" => \"123\"\nCODE>})\nCODE>\n\nRunning Sidekiq\n\nStart Sidekiq in foreground mode for development:\n\nCODE>bundle exec sidekiq -C config/sidekiq.yml -r ./inits/sidekiq.rb\n\nStart Sidekiq as daemon in background:\n\nCODE># Start as daemon\nCODE>bundle exec sidekiq -d -C config/sidekiq.yml -r ./inits/sidekiq.rb\nCODE>\nCODE># Stop daemon\nCODE>kill -TERM $(cat tmp/pids/sidekiq.pid)\nCODE>\nCODE># View logs\nCODE>tail -f log/sidekiq.log\n\nCreate helper scripts for convenience:\n\nCODE># bin/sidekiq_start\nCODE>#!/bin/bash\nCODE>bundle exec sidekiq -d\nCODE> -C config/sidekiq.yml\nCODE> -r ./inits/sidekiq.rb\nCODE> -L log/sidekiq.log\nCODE> -P tmp/pids/sidekiq.pid\nCODE>\nCODE>echo \"✓ Sidekiq started. PID: $(cat tmp/pids/sidekiq.pid)\"\n\nCODE># bin/sidekiq_stop\nCODE>#!/bin/bash\nCODE>if [ -f tmp/pids/sidekiq.pid ]; then\nCODE> kill -TERM $(cat tmp/pids/sidekiq.pid)\nCODE> rm tmp/pids/sidekiq.pid\nCODE> echo \"✓ Sidekiq stopped\"\nCODE>else\nCODE> echo \"✗ Sidekiq is not running\"\nCODE>fi\n\nMake them executable:\n\nCODE>chmod +x bin/sidekiq_start bin/sidekiq_stop\n\nSidekiq Web Dashboard\n\nCreate Sidekiq middleware for the web dashboard:\n\nCODE># inits/middlewares/sidekiq_middleware.rb\nCODE>require 'sidekiq/web'\nCODE>require 'rack/session'\nCODE>\nCODE>class SidekiqMiddleware\nCODE> def initialize(app)\nCODE> @app = app\nCODE>\nCODE> # Get or generate session secret\nCODE> session_secret = ENV.fetch('SESSION_SECRET') { generate_secret }\nCODE>\nCODE> # Build Sidekiq Web app with authentication\nCODE> @sidekiq_app = Rack::Builder.new do\nCODE> # Session support (required for CSRF protection)\nCODE> use Rack::Session::Cookie,\nCODE> secret: session_secret,\nCODE> same_site: true,\nCODE> max_age: 86400\nCODE>\nCODE> # Basic authentication\nCODE> use Rack::Auth::Basic, \"Sidekiq Dashboard\" do |username, password|\nCODE> username == ENV.fetch('SIDEKIQ_USERNAME', 'admin') &&\nCODE> password == ENV.fetch('SIDEKIQ_PASSWORD', 'password')\nCODE> end\nCODE>\nCODE> run Sidekiq::Web\nCODE> end\nCODE> end\nCODE>\nCODE> def call(env)\nCODE> if env['PATH_INFO'].start_with?('/sidekiq')\nCODE> # Route to Sidekiq Web UI\nCODE> env['SCRIPT_NAME'] = '/sidekiq'\nCODE> env['PATH_INFO'] = env['PATH_INFO'].sub(%r{^/sidekiq}, '') || '/'\nCODE> @sidekiq_app.call(env)\nCODE> else\nCODE> # Pass through to main app\nCODE> @app.call(env)\nCODE> end\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def generate_secret\nCODE> secret_file = '.session.key'\nCODE>\nCODE> if File.exist?(secret_file)\nCODE> File.read(secret_file).strip\nCODE> else\nCODE> require 'securerandom'\nCODE> secret = SecureRandom.hex(64)\nCODE> File.write(secret_file, secret)\nCODE> puts \"Generated new session secret in #{secret_file}\"\nCODE> secret\nCODE> end\nCODE> end\nCODE>end\n\nSet environment variables:\n\nCODE># .env\nCODE>REDIS_URL=redis://localhost:6379/0\nCODE>SIDEKIQ_USERNAME=admin\nCODE>SIDEKIQ_PASSWORD=your_secure_password\nCODE>SESSION_SECRET=generate_with_securerandom_hex_64\n\nGenerate SESSION_SECRET:\n\nCODE>ruby -e \"require 'securerandom'; puts SecureRandom.hex(64)\"\n\nAccess the dashboard - Start your Rubee application and visit:\n\nCODE>http://localhost:9292/sidekiq\n\nLogin with credentials from your .env file.\n\nWorker examples\n\nSimple email worker:\n\nCODE># app/workers/email_worker.rb\nCODE>class EmailWorker\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :mailers, retry: 5\nCODE>\nCODE> def perform(options)\nCODE> options = parse_options(options)\nCODE>\nCODE> Mailer.send_email(\nCODE> to: options['email'],\nCODE> subject: options['subject'],\nCODE> body: options['body']\nCODE> )\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def parse_options(options)\nCODE> return options unless options.is_a?(String)\nCODE> JSON.parse(options) rescue options\nCODE> end\nCODE>end\nCODE>\nCODE># Usage\nCODE>EmailWorker.new.perform_async({\nCODE> \"email\" => \"user@example.com\",\nCODE> \"subject\" => \"Welcome!\",\nCODE> \"body\" => \"Hello...\"\nCODE>}.to_json)\n\nWorker with database records:\n\nCODE># app/workers/booking_confirmation_worker.rb\nCODE>class BookingConfirmationWorker\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :mailers, retry: 3\nCODE>\nCODE> def perform(options)\nCODE> options = parse_options(options)\nCODE>\nCODE> # Fetch records from database\nCODE> service = Service.find(options['service_id'])\nCODE> time_slot = TimeSlot.find(options['time_slot_id'])\nCODE>\nCODE> Mailer.booking_confirmation(\nCODE> to: options['to'],\nCODE> client_name: options['client_name'],\nCODE> service: service,\nCODE> time_slot: time_slot\nCODE> )\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def parse_options(options)\nCODE> return options unless options.is_a?(String)\nCODE> JSON.parse(options) rescue options\nCODE> end\nCODE>end\nCODE>\nCODE># Usage\nCODE>BookingConfirmationWorker.new.perform_async({\nCODE> \"to\" => \"client@example.com\",\nCODE> \"client_name\" => \"John Doe\",\nCODE> \"service_id\" => 15,\nCODE> \"time_slot_id\" => 91\nCODE>})\n\nQueue priority\n\nConfigure queue processing priority in config/sidekiq.yml:\n\nCODE>:queues:\nCODE> - critical # Processed first\nCODE> - default\nCODE> - mailers\nCODE> - low # Processed last\n\nOr with weights where higher weight means more frequently processed:\n\nCODE>:queues:\nCODE> - [critical, 7]\nCODE> - [default, 5]\nCODE> - [mailers, 3]\nCODE> - [low, 1]\n\nMonitoring and troubleshooting\n\nCheck Sidekiq status:\n\nCODE># View running processes\nCODE>ps aux | grep sidekiq\nCODE>\nCODE># Check Redis connection\nCODE>redis-cli ping\nCODE>\nCODE># View queue sizes\nCODE>redis-cli LLEN queue:default\n\nView logs:\n\nCODE># Tail Sidekiq logs\nCODE>tail -f log/sidekiq.log\nCODE>\nCODE># View last 100 lines\nCODE>tail -n 100 log/sidekiq.log\n\nCommon issues - Workers not processing: Ensure Redis is running with redis-cli ping. Check Sidekiq is started with ps aux | grep sidekiq. Verify queue names match in worker and config.\n\nCommon issues - Authentication errors on Web UI: Ensure rack-session gem is installed. Check SESSION_SECRET is at least 64 bytes. Verify SIDEKIQ_USERNAME and SIDEKIQ_PASSWORD are set.\n\nCommon issues - Jobs failing: Check log/sidekiq.log for errors. View failed jobs in Web UI at /sidekiq/retries. Verify environment variables are loaded in inits/sidekiq.rb.\n\nBest practices\n\nPass IDs not objects - Use booking.id instead of the booking object itself to avoid serialization issues.\n\nKeep jobs small - Each job should do one thing and do it well.\n\nMake jobs idempotent - Jobs should be safe to run multiple times with the same result.\n\nSet appropriate retries - Use more retries for critical jobs and fewer for notifications.\n\nUse different queues - Separate critical jobs from low-priority jobs using different queue names.\n\nHandle JSON properly - Always parse options in the perform method to handle string arguments.\n\nMonitor your queues - Use the Web UI to watch for backlogs and failed jobs.\n\nAdditional resources - Sidekiq Official Documentation at https://github.com/sidekiq/sidekiq/wiki. Best Practices guide at https://github.com/sidekiq/sidekiq/wiki/Best-Practices. Error Handling guide at https://github.com/sidekiq/sidekiq/wiki/Error-Handling.\n\nThreadAsync engine\n\nThe default adapter is ThreadAsync. It is not yet recommended for production — use with caution.\n\n1. Do not define any adapter in config/base_configuration.rb; the default ThreadAsync will be used.\n2. Create a worker and process it:\n\nCODE># test_async_runner.rb\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\nCODE>\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })","parent":null,"vector":{"sidekiq":0.46808920777058943,"engine":0.010760671443002056,"adapter":0.043370080794161825,"allow":0.008626313212384279,"proces":0.03389151067429167,"background":0.020334906404575005,"job":0.08333765530928883,"redis":0.16945755337145835,"gem":0.02332152154267866,"add":0.009702378370253919,"gemfile":0.006778302134858335,"code":0.6782406470443273,"rack":0.033556985645181725,"session":0.08974824417923413,"requir":0.01118566188172724,"web":0.06410588869945295,"configure":0.0279641547043181,"desir":0.007808555283302602,"environment":0.021521342886004113,"config":0.07052587981461642,"base_configurate":0.01118566188172724,"base":0.009125155584838706,"configurate":0.02075244165432136,"setup":0.005380335721501028,"env":0.0824702161471583,"development":0.01455356755538088,"database_url":0.006410588869945296,"database":0.01455356755538088,"url":0.04150488330864272,"sqlite":0.006099691734331734,"async_adapter":0.017252626424768557,"async":0.05422641707886668,"sidekiqasync":0.008626313212384279,"end":0.09096345600535283,"install":0.016141007164503084,"dependency":0.006410588869945296,"bundle":0.028913387196107886,"start":0.04902983562685241,"must":0.007808555283302602,"running":0.031128662481482047,"before":0.00518811041358034,"starting":0.006099691734331734,"server":0.014105175962923284,"macos":0.007808555283302602,"homebrew":0.008626313212384279,"brew":0.007808555283302602,"services":0.007808555283302602,"verify":0.031234221133210407,"cli":0.025642355479781186,"ping":0.023425665849907806,"respond":0.008626313212384279,"pong":0.008626313212384279,"file":0.07017671439223185,"yml":0.03614173399513485,"concurrency":0.008626313212384279,"queues":0.03614173399513485,"default":0.03193804454693547,"mailer":0.0505984275931888,"critical":0.03389151067429167,"low":0.02711320853943334,"connecte":0.021685040397080912,"localhost":0.029151901928348326,"6379":0.028913387196107886,"optional":0.012821177739890593,"logging":0.008626313212384279,"verbose":0.008626313212384279,"false":0.006099691734331734,"logfile":0.008626313212384279,"log":0.10167453202287502,"pid":0.12493688453284163,"daemon":0.031234221133210407,"mode":0.01118566188172724,"pidfile":0.008626313212384279,"tmp":0.04744811494400834,"create":0.030171007004793072,"boot":0.008626313212384279,"init":0.034982282314017996,"configure_server":0.008626313212384279,"fetch":0.03846353321967178,"redis_url":0.021685040397080912,"configure_client":0.008626313212384279,"client":0.030498458671658672,"load":0.023425665849907806,"applicat":0.01118566188172724,"context":0.007228346799026971,"unles":0.025642355479781186,"object":0.01455356755538088,"const_defin":0.008626313212384279,"const":0.006778302134858335,"defin":0.007228346799026971,"require":0.043370080794161825,"variables":0.021685040397080912,"require_relative":0.007808555283302602,"relative":0.007808555283302602,"dev":0.01166076077133933,"exist":0.01355660426971667,"join":0.007228346799026971,"dir":0.008626313212384279,"trigger":0.008626313212384279,"autoload":0.017252626424768557,"call":0.024398766937326937,"worker":0.10167453202287502,"app":0.04741158243610339,"test_async_runner":0.015617110566605204,"test":0.008864827944624717,"runner":0.015617110566605204,"clas":0.019419836959463765,"testasyncrunner":0.039042776416513006,"include":0.03291207724682099,"asyncable":0.02711320853943334,"sidekiq_option":0.023425665849907806,"option":0.24384118943827596,"queue":0.057695299829507656,"retry":0.034982282314017996,"def":0.045625777924193534,"perform":0.06778302134858334,"parse_option":0.04685133169981561,"parse":0.06778302134858334,"user":0.012930431573482747,"email":0.06015146947905588,"password":0.07017671439223185,"private":0.02711320853943334,"return":0.020334906404575005,"is_a":0.023425665849907806,"string":0.02075244165432136,"begin":0.008626313212384279,"json":0.03193804454693547,"rescue":0.020334906404575005,"parsererror":0.008626313212384279,"codebase":0.008626313212384279,"enqueue":0.008626313212384279,"asynchronous":0.008626313212384279,"new":0.06015146947905588,"perform_async":0.028913387196107886,"com":0.04010097965270392,"123":0.018299075202995205,"to_json":0.015617110566605204,"schedule":0.007808555283302602,"minutes":0.008626313212384279,"300":0.017252626424768557,"second":0.007808555283302602,"perform_in":0.008626313212384279,"foreground":0.007808555283302602,"exec":0.023425665849907806,"stop":0.021685040397080912,"kill":0.015617110566605204,"term":0.015617110566605204,"cat":0.023425665849907806,"view":0.026594483833874156,"tail":0.028913387196107886,"helper":0.007228346799026971,"script":0.014456693598053943,"convenience":0.007808555283302602,"bin":0.04685133169981561,"sidekiq_start":0.015617110566605204,"bash":0.015617110566605204,"echo":0.023425665849907806,"sidekiq_stop":0.015617110566605204,"then":0.005830380385669665,"stopp":0.007808555283302602,"else":0.01923176660983589,"not":0.025063112282939944,"them":0.007228346799026971,"executable":0.007808555283302602,"chmod":0.007808555283302602,"dashboard":0.031234221133210407,"middleware":0.014456693598053943,"middlewares":0.007228346799026971,"sidekiq_middleware":0.007808555283302602,"sidekiqmiddleware":0.007808555283302602,"initialize":0.005830380385669665,"generate":0.02155071928913791,"secret":0.12878774056230835,"session_secret":0.043370080794161825,"generate_secret":0.015617110566605204,"build":0.005830380385669665,"authenticat":0.016778492822590862,"sidekiq_app":0.015617110566605204,"builder":0.007808555283302602,"support":0.004562577792419353,"csrf":0.007808555283302602,"protecte":0.007808555283302602,"cookie":0.007808555283302602,"same_site":0.007808555283302602,"same":0.014456693598053943,"site":0.006778302134858335,"true":0.00501262245658799,"max_age":0.007808555283302602,"max":0.006778302134858335,"age":0.007228346799026971,"86400":0.007808555283302602,"basic":0.015617110566605204,"auth":0.006410588869945296,"username":0.03614173399513485,"sidekiq_username":0.021685040397080912,"admin":0.01355660426971667,"sidekiq_password":0.021685040397080912,"path_info":0.023425665849907806,"path":0.017491141157008998,"info":0.018299075202995205,"start_with":0.007808555283302602,"route":0.00559283094086362,"script_name":0.007808555283302602,"name":0.018250311169677413,"sub":0.007228346799026971,"pas":0.01166076077133933,"through":0.007228346799026971,"main":0.005380335721501028,"secret_file":0.039042776416513006,"key":0.005380335721501028,"read":0.006410588869945296,"strip":0.007808555283302602,"securerandom":0.039042776416513006,"hex":0.023425665849907806,"write":0.005830380385669665,"put":0.012821177739890593,"generat":0.005830380385669665,"your_secure_password":0.007808555283302602,"secure":0.007808555283302602,"generate_with_securerandom_hex_64":0.007808555283302602,"ruby":0.00501262245658799,"acces":0.007808555283302602,"visit":0.007808555283302602,"http":0.017729655889249435,"9292":0.007808555283302602,"login":0.006778302134858335,"credential":0.007228346799026971,"examples":0.007808555283302602,"simple":0.006778302134858335,"email_worker":0.007808555283302602,"emailworker":0.015617110566605204,"send_email":0.007808555283302602,"send":0.007808555283302602,"subject":0.023425665849907806,"body":0.021685040397080912,"usage":0.015617110566605204,"welcome":0.006099691734331734,"hello":0.006778302134858335,"record":0.01355660426971667,"booking_confirmation_worker":0.007808555283302602,"booking":0.028913387196107886,"confirmate":0.015617110566605204,"bookingconfirmationworker":0.015617110566605204,"service":0.04685133169981561,"find":0.012199383468663469,"service_id":0.015617110566605204,"time_slot":0.023425665849907806,"time":0.029151901928348326,"slot":0.039042776416513006,"timeslot":0.007808555283302602,"time_slot_id":0.015617110566605204,"booking_confirmate":0.007808555283302602,"client_name":0.023425665849907806,"john":0.007808555283302602,"doe":0.007808555283302602,"priority":0.021685040397080912,"processing":0.014456693598053943,"first":0.00501262245658799,"last":0.01166076077133933,"weight":0.01166076077133933,"higher":0.007228346799026971,"mean":0.007808555283302602,"more":0.012199383468663469,"frequent":0.007808555283302602,"monitoring":0.007808555283302602,"troubleshooting":0.007808555283302602,"check":0.03389151067429167,"status":0.007228346799026971,"processes":0.007808555283302602,"aux":0.015617110566605204,"grep":0.015617110566605204,"sizes":0.007808555283302602,"llen":0.007808555283302602,"100":0.014456693598053943,"lines":0.007808555283302602,"common":0.023425665849907806,"issues":0.028913387196107886,"ensure":0.014456693598053943,"names":0.014456693598053943,"match":0.006778302134858335,"error":0.021521342886004113,"least":0.007228346799026971,"bytes":0.007808555283302602,"failing":0.007808555283302602,"fail":0.01355660426971667,"best":0.023425665849907806,"practices":0.023425665849907806,"id":0.007808555283302602,"instead":0.007228346799026971,"itself":0.007808555283302602,"avoid":0.007808555283302602,"serializate":0.007808555283302602,"keep":0.007808555283302602,"small":0.007808555283302602,"each":0.006410588869945296,"one":0.0048511891851269594,"thing":0.007808555283302602,"well":0.007808555283302602,"idempotent":0.007808555283302602,"safe":0.007808555283302602,"multiple":0.007808555283302602,"times":0.007808555283302602,"result":0.006778302134858335,"appropriate":0.007808555283302602,"fewer":0.007808555283302602,"notificate":0.007808555283302602,"different":0.015617110566605204,"separate":0.007808555283302602,"handle":0.014456693598053943,"proper":0.007808555283302602,"alway":0.007808555283302602,"method":0.00501262245658799,"argument":0.006410588869945296,"monitor":0.007808555283302602,"watch":0.006410588869945296,"backlog":0.007808555283302602,"additional":0.007808555283302602,"resources":0.007808555283302602,"official":0.007808555283302602,"documentate":0.005830380385669665,"github":0.021685040397080912,"wiki":0.023425665849907806,"guide":0.01355660426971667,"handling":0.015617110566605204,"threadasync":0.021685040397080912,"yet":0.007808555283302602,"recommend":0.007228346799026971,"producte":0.005830380385669665,"caute":0.007808555283302602,"define":0.006410588869945296,"any":0.00501262245658799,"us":0.007228346799026971}},{"label":"Sidekiq engine — Running Sidekiq","body":"Start Sidekiq in foreground mode for development:\n\nCODE>bundle exec sidekiq -C config/sidekiq.yml -r ./inits/sidekiq.rb\n\nStart Sidekiq as daemon in background:\n\nCODE># Start as daemon\nCODE>bundle exec sidekiq -d -C config/sidekiq.yml -r ./inits/sidekiq.rb\nCODE>\nCODE># Stop daemon\nCODE>kill -TERM $(cat tmp/pids/sidekiq.pid)\nCODE>\nCODE># View logs\nCODE>tail -f log/sidekiq.log\n\nCreate helper scripts for convenience:\n\nCODE># bin/sidekiq_start\nCODE>#!/bin/bash\nCODE>bundle exec sidekiq -d\nCODE> -C config/sidekiq.yml\nCODE> -r ./inits/sidekiq.rb\nCODE> -L log/sidekiq.log\nCODE> -P tmp/pids/sidekiq.pid\nCODE>\nCODE>echo \"✓ Sidekiq started. PID: $(cat tmp/pids/sidekiq.pid)\"\n\nCODE># bin/sidekiq_stop\nCODE>#!/bin/bash\nCODE>if [ -f tmp/pids/sidekiq.pid ]; then\nCODE> kill -TERM $(cat tmp/pids/sidekiq.pid)\nCODE> rm tmp/pids/sidekiq.pid\nCODE> echo \"✓ Sidekiq stopped\"\nCODE>else\nCODE> echo \"✗ Sidekiq is not running\"\nCODE>fi\n\nMake them executable:\n\nCODE>chmod +x bin/sidekiq_start bin/sidekiq_stop","parent":"Sidekiq engine","vector":{"sidekiq":0.6796198263470001,"engine":0.024272136655250007,"running":0.04680991352926808,"start":0.11059336555557907,"foreground":0.03522648599026815,"mode":0.02523075954979259,"development":0.021885014790308008,"code":0.2964439798363637,"bundle":0.09782702997308942,"exec":0.10567945797080441,"config":0.06363222970460063,"yml":0.09782702997308942,"init":0.07890722631351861,"daemon":0.10567945797080441,"background":0.03057873787510695,"stop":0.09782702997308942,"kill":0.0704529719805363,"term":0.0704529719805363,"cat":0.10567945797080441,"tmp":0.1834724272506417,"pid":0.4579443178734859,"view":0.01999580755131593,"log":0.15289368937553474,"tail":0.03260900999102981,"create":0.019444214289994384,"helper":0.03260900999102981,"script":0.03260900999102981,"convenience":0.03522648599026815,"bin":0.21135891594160883,"sidekiq_start":0.0704529719805363,"bash":0.0704529719805363,"echo":0.10567945797080441,"sidekiq_stop":0.0704529719805363,"then":0.02630240877117287,"stopp":0.03522648599026815,"else":0.0289198847704112,"not":0.02261328355055426,"them":0.03260900999102981,"executable":0.03522648599026815,"chmod":0.03522648599026815}},{"label":"Sidekiq engine — Sidekiq Web Dashboard","body":"Create Sidekiq middleware for the web dashboard:\n\nCODE># inits/middlewares/sidekiq_middleware.rb\nCODE>require 'sidekiq/web'\nCODE>require 'rack/session'\nCODE>\nCODE>class SidekiqMiddleware\nCODE> def initialize(app)\nCODE> @app = app\nCODE>\nCODE> # Get or generate session secret\nCODE> session_secret = ENV.fetch('SESSION_SECRET') { generate_secret }\nCODE>\nCODE> # Build Sidekiq Web app with authentication\nCODE> @sidekiq_app = Rack::Builder.new do\nCODE> # Session support (required for CSRF protection)\nCODE> use Rack::Session::Cookie,\nCODE> secret: session_secret,\nCODE> same_site: true,\nCODE> max_age: 86400\nCODE>\nCODE> # Basic authentication\nCODE> use Rack::Auth::Basic, \"Sidekiq Dashboard\" do |username, password|\nCODE> username == ENV.fetch('SIDEKIQ_USERNAME', 'admin') &&\nCODE> password == ENV.fetch('SIDEKIQ_PASSWORD', 'password')\nCODE> end\nCODE>\nCODE> run Sidekiq::Web\nCODE> end\nCODE> end\nCODE>\nCODE> def call(env)\nCODE> if env['PATH_INFO'].start_with?('/sidekiq')\nCODE> # Route to Sidekiq Web UI\nCODE> env['SCRIPT_NAME'] = '/sidekiq'\nCODE> env['PATH_INFO'] = env['PATH_INFO'].sub(%r{^/sidekiq}, '') || '/'\nCODE> @sidekiq_app.call(env)\nCODE> else\nCODE> # Pass through to main app\nCODE> @app.call(env)\nCODE> end\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def generate_secret\nCODE> secret_file = '.session.key'\nCODE>\nCODE> if File.exist?(secret_file)\nCODE> File.read(secret_file).strip\nCODE> else\nCODE> require 'securerandom'\nCODE> secret = SecureRandom.hex(64)\nCODE> File.write(secret_file, secret)\nCODE> puts \"Generated new session secret in #{secret_file}\"\nCODE> secret\nCODE> end\nCODE> end\nCODE>end\n\nSet environment variables:\n\nCODE># .env\nCODE>REDIS_URL=redis://localhost:6379/0\nCODE>SIDEKIQ_USERNAME=admin\nCODE>SIDEKIQ_PASSWORD=your_secure_password\nCODE>SESSION_SECRET=generate_with_securerandom_hex_64\n\nGenerate SESSION_SECRET:\n\nCODE>ruby -e \"require 'securerandom'; puts SecureRandom.hex(64)\"\n\nAccess the dashboard - Start your Rubee application and visit:\n\nCODE>http://localhost:9292/sidekiq\n\nLogin with credentials from your .env file.","parent":"Sidekiq engine","vector":{"sidekiq":0.36513160299539993,"engine":0.019217452789231572,"web":0.1373838310502055,"dashboard":0.11156221490736867,"create":0.015394947525595996,"middleware":0.0516363366692442,"code":0.5364785867678689,"init":0.020824919782814182,"middlewares":0.0258181683346221,"sidekiq_middleware":0.02789055372684217,"require":0.1032726733384884,"rack":0.07990576806178558,"session":0.2518703569253767,"clas":0.013872732827867199,"sidekiqmiddleware":0.02789055372684217,"def":0.04888976888893117,"initialize":0.020824919782814182,"app":0.12315958020476797,"generate":0.07697473762797999,"secret":0.4357926241387109,"session_secret":0.1290908416731105,"env":0.2079294020949291,"fetch":0.06869191552510275,"generate_secret":0.05578110745368434,"build":0.020824919782814182,"authenticat":0.03995288403089279,"sidekiq_app":0.05578110745368434,"builder":0.02789055372684217,"new":0.03580811324645265,"support":0.016296589629643723,"requir":0.019976442015446395,"csrf":0.02789055372684217,"protecte":0.02789055372684217,"cookie":0.02789055372684217,"same_site":0.02789055372684217,"same":0.0258181683346221,"site":0.024210701341039496,"true":0.017904056623226326,"max_age":0.02789055372684217,"max":0.024210701341039496,"age":0.0258181683346221,"86400":0.02789055372684217,"basic":0.05578110745368434,"auth":0.022897305175034247,"username":0.1032726733384884,"password":0.10742433973935797,"sidekiq_username":0.0516363366692442,"admin":0.04842140268207899,"sidekiq_password":0.0516363366692442,"end":0.10830091973272646,"call":0.06536053361778892,"path_info":0.0836716611805265,"path":0.06247475934844255,"info":0.06536053361778892,"start_with":0.02789055372684217,"start":0.02918741506710147,"route":0.019976442015446395,"script_name":0.02789055372684217,"script":0.0258181683346221,"name":0.016296589629643723,"sub":0.0258181683346221,"else":0.045794610350068495,"pas":0.020824919782814182,"through":0.0258181683346221,"main":0.019217452789231572,"private":0.024210701341039496,"secret_file":0.13945276863421086,"file":0.16113650960903694,"key":0.019217452789231572,"exist":0.024210701341039496,"read":0.022897305175034247,"strip":0.02789055372684217,"securerandom":0.13945276863421086,"hex":0.0836716611805265,"write":0.020824919782814182,"put":0.045794610350068495,"generat":0.020824919782814182,"environment":0.019217452789231572,"variables":0.0258181683346221,"redis_url":0.0258181683346221,"redis":0.04842140268207899,"url":0.018530863518398725,"localhost":0.041649839565628365,"6379":0.0258181683346221,"your_secure_password":0.02789055372684217,"secure":0.02789055372684217,"generate_with_securerandom_hex_64":0.02789055372684217,"ruby":0.017904056623226326,"acces":0.02789055372684217,"applicat":0.019976442015446395,"visit":0.02789055372684217,"http":0.01583167123100626,"9292":0.02789055372684217,"login":0.024210701341039496,"credential":0.0258181683346221}},{"label":"Sidekiq engine — Worker examples","body":"Simple email worker:\n\nCODE># app/workers/email_worker.rb\nCODE>class EmailWorker\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :mailers, retry: 5\nCODE>\nCODE> def perform(options)\nCODE> options = parse_options(options)\nCODE>\nCODE> Mailer.send_email(\nCODE> to: options['email'],\nCODE> subject: options['subject'],\nCODE> body: options['body']\nCODE> )\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def parse_options(options)\nCODE> return options unless options.is_a?(String)\nCODE> JSON.parse(options) rescue options\nCODE> end\nCODE>end\nCODE>\nCODE># Usage\nCODE>EmailWorker.new.perform_async({\nCODE> \"email\" => \"user@example.com\",\nCODE> \"subject\" => \"Welcome!\",\nCODE> \"body\" => \"Hello...\"\nCODE>}.to_json)\n\nWorker with database records:\n\nCODE># app/workers/booking_confirmation_worker.rb\nCODE>class BookingConfirmationWorker\nCODE> include Rubee::Asyncable\nCODE> include Sidekiq::Worker\nCODE>\nCODE> sidekiq_options queue: :mailers, retry: 3\nCODE>\nCODE> def perform(options)\nCODE> options = parse_options(options)\nCODE>\nCODE> # Fetch records from database\nCODE> service = Service.find(options['service_id'])\nCODE> time_slot = TimeSlot.find(options['time_slot_id'])\nCODE>\nCODE> Mailer.booking_confirmation(\nCODE> to: options['to'],\nCODE> client_name: options['client_name'],\nCODE> service: service,\nCODE> time_slot: time_slot\nCODE> )\nCODE> end\nCODE>\nCODE> private\nCODE>\nCODE> def parse_options(options)\nCODE> return options unless options.is_a?(String)\nCODE> JSON.parse(options) rescue options\nCODE> end\nCODE>end\nCODE>\nCODE># Usage\nCODE>BookingConfirmationWorker.new.perform_async({\nCODE> \"to\" => \"client@example.com\",\nCODE> \"client_name\" => \"John Doe\",\nCODE> \"service_id\" => 15,\nCODE> \"time_slot_id\" => 91\nCODE>})","parent":"Sidekiq engine","vector":{"sidekiq":0.10047413752464654,"engine":0.020094827504929306,"worker":0.22784438983752672,"examples":0.02916389972722638,"simple":0.025316043315280742,"email":0.09360734053261753,"code":0.5960322930482853,"app":0.03219561076769111,"email_worker":0.02916389972722638,"clas":0.029012187645822588,"emailworker":0.05832779945445276,"include":0.07024123712055723,"asyncable":0.050632086630561485,"sidekiq_option":0.05832779945445276,"option":0.5619298660496663,"queue":0.047885367833749894,"mailer":0.10798759749641183,"retry":0.04355136712750305,"def":0.06816244819080518,"perform":0.10126417326112297,"parse_option":0.11665559890890552,"parse":0.15189625989168448,"send_email":0.02916389972722638,"send":0.02916389972722638,"subject":0.08749169918167914,"body":0.08099069812230889,"end":0.08493405673437407,"private":0.050632086630561485,"return":0.050632086630561485,"unles":0.047885367833749894,"is_a":0.05832779945445276,"string":0.038753783865494225,"json":0.05112183614310388,"rescue":0.050632086630561485,"usage":0.05832779945445276,"new":0.03744293621304702,"perform_async":0.053993798748205916,"async":0.050632086630561485,"user":0.016097805383845556,"com":0.03744293621304702,"welcome":0.022781525090490744,"hello":0.025316043315280742,"to_json":0.02916389972722638,"database":0.03623707326639029,"record":0.050632086630561485,"booking_confirmation_worker":0.02916389972722638,"booking":0.053993798748205916,"confirmate":0.05832779945445276,"bookingconfirmationworker":0.05832779945445276,"fetch":0.023942683916874947,"service":0.17498339836335827,"find":0.04556305018098149,"service_id":0.05832779945445276,"time_slot":0.08749169918167914,"time":0.10887841781875762,"slot":0.14581949863613192,"timeslot":0.02916389972722638,"time_slot_id":0.05832779945445276,"booking_confirmate":0.02916389972722638,"client_name":0.08749169918167914,"client":0.09112610036196298,"name":0.05112183614310388,"john":0.02916389972722638,"doe":0.02916389972722638}},{"label":"Sidekiq engine — Queue priority","body":"Configure queue processing priority in config/sidekiq.yml:\n\nCODE>:queues:\nCODE> - critical # Processed first\nCODE> - default\nCODE> - mailers\nCODE> - low # Processed last\n\nOr with weights where higher weight means more frequently processed:\n\nCODE>:queues:\nCODE> - [critical, 7]\nCODE> - [default, 5]\nCODE> - [mailers, 3]\nCODE> - [low, 1]","parent":"Sidekiq engine","vector":{"sidekiq":0.19928529369449732,"engine":0.09964264684724866,"queue":0.23744542196435872,"priority":0.2677348197833075,"configure":0.10357801207270495,"processing":0.13386740989165374,"config":0.08707492988930436,"yml":0.13386740989165374,"code":0.434632152384353,"queues":0.2677348197833075,"critical":0.2510653612742264,"proces":0.37659804191133966,"first":0.0928326771923148,"default":0.16899589587554853,"mailer":0.2677348197833075,"low":0.2510653612742264,"last":0.10797737610178922,"weight":0.21595475220357843,"higher":0.13386740989165374,"mean":0.14461274477204392,"more":0.11296496367916892,"frequent":0.14461274477204392}},{"label":"Sidekiq engine — Monitoring and troubleshooting","body":"Check Sidekiq status:\n\nCODE># View running processes\nCODE>ps aux | grep sidekiq\nCODE>\nCODE># Check Redis connection\nCODE>redis-cli ping\nCODE>\nCODE># View queue sizes\nCODE>redis-cli LLEN queue:default\n\nView logs:\n\nCODE># Tail Sidekiq logs\nCODE>tail -f log/sidekiq.log\nCODE>\nCODE># View last 100 lines\nCODE>tail -n 100 log/sidekiq.log\n\nCommon issues - Workers not processing: Ensure Redis is running with redis-cli ping. Check Sidekiq is started with ps aux | grep sidekiq. Verify queue names match in worker and config.\n\nCommon issues - Authentication errors on Web UI: Ensure rack-session gem is installed. Check SESSION_SECRET is at least 64 bytes. Verify SIDEKIQ_USERNAME and SIDEKIQ_PASSWORD are set.\n\nCommon issues - Jobs failing: Check log/sidekiq.log for errors. View failed jobs in Web UI at /sidekiq/retries. Verify environment variables are loaded in inits/sidekiq.rb.","parent":"Sidekiq engine","vector":{"sidekiq":0.5215653044006189,"engine":0.04012040803081684,"monitoring":0.05822730036070875,"troubleshooting":0.05822730036070875,"check":0.2527242364448626,"status":0.053900767159619604,"code":0.22750203656086498,"view":0.16525944321654124,"running":0.07737402179940656,"processes":0.05822730036070875,"aux":0.1164546007214175,"grep":0.1164546007214175,"redis":0.2527242364448626,"connecte":0.053900767159619604,"cli":0.1434085833076592,"ping":0.1164546007214175,"queue":0.1434085833076592,"sizes":0.05822730036070875,"llen":0.05822730036070875,"default":0.0340225019737503,"log":0.40435877831178013,"tail":0.1617023014788588,"last":0.04347632790146393,"100":0.10780153431923921,"lines":0.05822730036070875,"common":0.17468190108212625,"issues":0.1617023014788588,"worker":0.10108969457794503,"not":0.03737842184439739,"processing":0.053900767159619604,"ensure":0.10780153431923921,"start":0.03046738333899001,"verify":0.17468190108212625,"names":0.053900767159619604,"match":0.050544847288972516,"config":0.035060105556701415,"authenticat":0.041704955045486526,"error":0.08024081606163368,"web":0.09560572220510613,"rack":0.041704955045486526,"session":0.09560572220510613,"gem":0.04347632790146393,"install":0.04012040803081684,"session_secret":0.053900767159619604,"secret":0.050544847288972516,"least":0.053900767159619604,"bytes":0.05822730036070875,"sidekiq_username":0.053900767159619604,"username":0.053900767159619604,"sidekiq_password":0.053900767159619604,"password":0.03737842184439739,"job":0.09560572220510613,"failing":0.05822730036070875,"fail":0.050544847288972516,"retry":0.04347632790146393,"environment":0.04012040803081684,"variables":0.053900767159619604,"load":0.05822730036070875,"init":0.04347632790146393}},{"label":"Sidekiq engine — Best practices","body":"Pass IDs not objects - Use booking.id instead of the booking object itself to avoid serialization issues.\n\nKeep jobs small - Each job should do one thing and do it well.\n\nMake jobs idempotent - Jobs should be safe to run multiple times with the same result.\n\nSet appropriate retries - Use more retries for critical jobs and fewer for notifications.\n\nUse different queues - Separate critical jobs from low-priority jobs using different queue names.\n\nHandle JSON properly - Always parse options in the perform method to handle string arguments.\n\nMonitor your queues - Use the Web UI to watch for backlogs and failed jobs.\n\nAdditional resources - Sidekiq Official Documentation at https://github.com/sidekiq/sidekiq/wiki. Best Practices guide at https://github.com/sidekiq/sidekiq/wiki/Best-Practices. Error Handling guide at https://github.com/sidekiq/sidekiq/wiki/Error-Handling.","parent":"Sidekiq engine","vector":{"sidekiq":0.4064986208854906,"engine":0.050812327610686325,"best":0.22123389120631007,"practices":0.22123389120631007,"pas":0.05506258597724014,"id":0.07374463040210336,"not":0.04733961366666802,"object":0.09163004947480113,"booking":0.1365301886899156,"instead":0.0682650943449578,"itself":0.07374463040210336,"avoid":0.07374463040210336,"serializate":0.07374463040210336,"issues":0.0682650943449578,"keep":0.07374463040210336,"job":0.4843369762750855,"small":0.07374463040210336,"each":0.060542122034385686,"one":0.04581502473740057,"thing":0.07374463040210336,"well":0.07374463040210336,"idempotent":0.07374463040210336,"safe":0.07374463040210336,"multiple":0.07374463040210336,"times":0.07374463040210336,"same":0.0682650943449578,"result":0.064014835978404,"appropriate":0.07374463040210336,"retry":0.11012517195448028,"more":0.05760598423077424,"critical":0.128029671956808,"fewer":0.07374463040210336,"notificate":0.07374463040210336,"different":0.1474892608042067,"queues":0.1365301886899156,"separate":0.07374463040210336,"low":0.064014835978404,"priority":0.0682650943449578,"queue":0.060542122034385686,"names":0.0682650943449578,"handle":0.1365301886899156,"json":0.043089355300114214,"proper":0.07374463040210336,"alway":0.07374463040210336,"parse":0.064014835978404,"option":0.048996936187787145,"perform":0.064014835978404,"method":0.04733961366666802,"string":0.048996936187787145,"argument":0.060542122034385686,"monitor":0.07374463040210336,"web":0.060542122034385686,"watch":0.060542122034385686,"backlog":0.07374463040210336,"fail":0.064014835978404,"additional":0.07374463040210336,"resources":0.07374463040210336,"official":0.07374463040210336,"documentate":0.05506258597724014,"http":0.12558023282856742,"github":0.2047952830348734,"com":0.14201884100000406,"wiki":0.22123389120631007,"guide":0.128029671956808,"error":0.10162465522137265,"handling":0.1474892608042067}},{"label":"Sidekiq engine — ThreadAsync engine","body":"The default adapter is ThreadAsync. It is not yet recommended for production — use with caution.\n\n1. Do not define any adapter in config/base_configuration.rb; the default ThreadAsync will be used.\n2. Create a worker and process it:\n\nCODE># test_async_runner.rb\nCODE>class TestAsyncRunner\nCODE> include Rubee::Asyncable\nCODE>\nCODE> def perform(options)\nCODE> User.create(email: options['email'], password: options['password'])\nCODE> end\nCODE>end\nCODE>\nCODE>TestAsyncRunner.new.perform_async(options: { \"email\" => \"new@new.com\", \"password\" => \"123\" })","parent":"Sidekiq engine","vector":{"sidekiq":0.08196168248801364,"engine":0.16392336497602727,"threadasync":0.33034042627909554,"default":0.13900863132191657,"adapter":0.22022695085273036,"not":0.15272019869590334,"yet":0.11895211785066802,"recommend":0.11011347542636518,"producte":0.08881746617500702,"caute":0.11895211785066802,"define":0.09765610859930984,"any":0.07636009934795167,"config":0.07162402828573872,"base_configurate":0.08519874177225448,"base":0.06950431566095829,"configurate":0.07903340617414066,"us":0.11011347542636518,"create":0.1313176948944631,"worker":0.10325769173937181,"proces":0.10325769173937181,"code":0.3575093958254475,"test_async_runner":0.11895211785066802,"test":0.06752145692364885,"async":0.20651538347874362,"runner":0.11895211785066802,"clas":0.05916666145868337,"testasyncrunner":0.23790423570133604,"include":0.07162402828573872,"asyncable":0.10325769173937181,"def":0.06950431566095829,"perform":0.20651538347874362,"option":0.31613362469656264,"user":0.06565884744723155,"email":0.229080298043855,"password":0.229080298043855,"end":0.11547479384556499,"new":0.229080298043855,"perform_async":0.11011347542636518,"com":0.07636009934795167,"123":0.09292003753709689}},{"label":"Logger","body":"Use your own logger by setting it in config/base_configuration.rb:\n\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> config.database_url = { url: \"sqlite://db/development.db\", env: }\nCODE> config.logger = { logger: MyLogger, env: }\nCODE>end\n\nOr use the built-in logger with its full set of levels:\n\nCODE># app/controllers/welcome_controller.rb\nCODE>class WelcomeController (&target_method) do\nCODE> start = Time.now\nCODE> Rubee::Logger.warn(message: 'This is a warning message', method: :show, class_name: 'WelcomeController')\nCODE> Rubee::Logger.error(message: 'This is an error message', class_name: 'WelcomeController')\nCODE> Rubee::Logger.critical(message: 'We are on fire!')\nCODE> target_method.call\nCODE> Rubee::Logger.info(\nCODE> message: \"Execution Time: #{Time.now - start} seconds\",\nCODE> method: :show,\nCODE> class_name: 'WelcomeController'\nCODE> )\nCODE> Rubee::Logger.debug(object: User.last, method: :show, class_name: 'WelcomeController')\nCODE> end\nCODE>\nCODE> def show\nCODE> response_with\nCODE> end\nCODE>end\n\nOutput:\n\nCODE>[2025-04-26 12:32:33] WARN [method: show][class_name: WelcomeController] This is a warning message\nCODE>[2025-04-26 12:32:33] ERROR [class_name: WelcomeController] This is an error message\nCODE>[2025-04-26 12:32:33] CRITICAL We are on fire!\nCODE>[2025-04-26 12:32:33] INFO [method: show][class_name: WelcomeController] Execution Time: 0.000655 seconds\nCODE>[2025-04-26 12:32:33] DEBUG [method: show][class_name: WelcomeController] #","parent":null,"vector":{"logger":0.3947171102636825,"own":0.0350061941435067,"setting":0.04710556255934064,"config":0.10269852753597451,"base_configurate":0.03054067726064514,"base":0.024914791329871545,"configurate":0.0566612534543311,"code":0.35883184159305287,"setup":0.029380308212733096,"env":0.07947242003192924,"development":0.0529816133546195,"database_url":0.0350061941435067,"database":0.02649080667730975,"url":0.0566612534543311,"sqlite":0.03330848341696601,"mylogger":0.04710556255934064,"end":0.08278710077677268,"built":0.0350061941435067,"full":0.029380308212733096,"level":0.04710556255934064,"app":0.02353632961566646,"controller":0.0529816133546195,"welcome_controller":0.039471711026368254,"welcome":0.03330848341696601,"clas":0.19088203501018863,"welcomecontroller":0.35524539923731424,"target_method":0.09421112511868128,"target":0.08528009135295817,"method":0.21897874088427452,"start":0.04462273226371227,"time":0.1273514379735835,"now":0.09421112511868128,"warn":0.09421112511868128,"message":0.31577368821094604,"warning":0.09421112511868128,"class_name":0.3768445004747251,"name":0.19931833063897236,"error":0.11752123285093238,"critical":0.07402831949141096,"fire":0.09421112511868128,"call":0.03330848341696601,"info":0.06661696683393202,"execute":0.08528009135295817,"second":0.08528009135295817,"debug":0.07894342205273651,"object":0.02649080667730975,"user":0.02353632961566646,"last":0.031837859493395876,"def":0.024914791329871545,"response_with":0.03054067726064514,"response":0.02833062672716555,"output":0.0350061941435067,"2025":0.2132002283823954,"000655":0.04710556255934064}},{"label":"WebSocket","body":"With ru.Bee 2.0.0 you can use WebSocket with ease.\n\n1. Install and start Redis\n\nCODE>sudo apt-get install -y redis # Linux\nCODE>brew install redis # macOS\n\n2. Add the required gems to your Gemfile\n\nCODE>gem 'ru.Bee'\nCODE>gem 'redis'\nCODE>gem 'websocket'\n\n3. Add the Redis URL to your configuration, unless it defaults to 127.0.0.1:6379\n\nCODE># config/base_configuration.rb\nCODE>Rubee::Configuration.setup(env = :development) do |config|\nCODE> ...\nCODE> config.redis_url = { url: \"redis://localhost:6378/0\", env: }\nCODE>end\n\n4. Add a WebSocket entry route\n\nCODE># config/routes.rb\nCODE>Rubee::Router.draw do |router|\nCODE> ...\nCODE> router.get('/ws', to: 'users#websocket')\nCODE> # On the client: const ws = new WebSocket(\"ws://website/ws\");\nCODE>end\n\n5. Make the model pub/sub capable\n\nCODE># app/models/user.rb\nCODE>class User e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>\nCODE> # Expected client params: { action: 'unsubscribe', channel: 'default', id: '123', subscriber: 'User' }\nCODE> def unsubscribe\nCODE> channel = params[:channel]\nCODE> sender_id = params[:options][:id]\nCODE> io = params[:options][:io]\nCODE>\nCODE> User.unsub(channel, sender_id, io) do |channel, args|\nCODE> websocket_connections.remove(channel, args[:io])\nCODE> end\nCODE> response_with(object: params.merge(type: 'system', status: :unsubscribed), type: :websocket)\nCODE> rescue StandardError => e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>\nCODE> # Expected client params: { action: 'publish', channel: 'default', message: 'Hello', id: '123', subscriber: 'User' }\nCODE> def publish\nCODE> args = {}\nCODE> User.pub(params[:channel], message: params[:message]) do |channel|\nCODE> user = User.find(params[:options][:id])\nCODE> args[:message] = params[:message]\nCODE> args[:sender] = params[:options][:id]\nCODE> args[:sender_name] = user.email\nCODE> websocket_connections.stream(channel, args)\nCODE> end\nCODE> response_with(object: { type: 'system', message: params[:message], status: :published }, type: :websocket)\nCODE> rescue StandardError => e\nCODE> response_with(object: { type: 'system', error: e.message }, type: :websocket)\nCODE> end\nCODE>end\n\nFor a full chat application example, see rubee-chat.","parent":null,"vector":{"websocket":0.33975236728861485,"ease":0.030107098637609426,"install":0.062234162041626746,"start":0.015753512694808115,"redis":0.18294358238617722,"code":0.4524329132795029,"sudo":0.03326009144348685,"apt":0.03326009144348685,"linux":0.03326009144348685,"brew":0.030107098637609426,"macos":0.030107098637609426,"add":0.056113541880905234,"requir":0.02156402902853465,"gem":0.08991975134836855,"gemfile":0.026134797483739598,"url":0.060010698380459485,"configurate":0.060010698380459485,"unles":0.02471702183441207,"default":0.05277518362399449,"127":0.030107098637609426,"6379":0.027870014640289487,"config":0.07251293119904893,"base_configurate":0.02156402902853465,"base":0.017591727874664828,"setup":0.020744720680542245,"env":0.03740902792060349,"development":0.018704513960301743,"redis_url":0.027870014640289487,"localhost":0.022479937837092137,"6378":0.03326009144348685,"end":0.1169079145889798,"entry":0.03326009144348685,"route":0.02156402902853465,"routes":0.019326945031214716,"router":0.062234162041626746,"draw":0.02156402902853465,"user":0.16618429602129597,"client":0.07055492880887877,"const":0.026134797483739598,"new":0.019326945031214716,"website":0.03326009144348685,"model":0.030709287754689788,"pub":0.0665201828869737,"sub":0.027870014640289487,"capable":0.03326009144348685,"app":0.016618429602129597,"clas":0.01497523999388482,"response_with":0.10782014514267324,"response":0.10001783063409914,"object":0.09352256980150872,"type":0.18128232799762237,"system":0.16630045721743422,"error":0.062234162041626746,"message":0.27870014640289487,"expect":0.0665201828869737,"param":0.3344401756834739,"acte":0.04703661920591918,"unsubscribe":0.0665201828869737,"channel":0.33260091443486844,"123":0.04703661920591918,"subscriber":0.0665201828869737,"def":0.035183455749329656,"sender_id":0.0665201828869737,"sender":0.1330403657739474,"option":0.0800142645072793,"unsub":0.03326009144348685,"arg":0.23282064010440792,"websocket_connection":0.0665201828869737,"connection":0.05574002928057897,"remove":0.03326009144348685,"merge":0.03326009144348685,"status":0.05574002928057897,"unsubscrib":0.03326009144348685,"rescue":0.052269594967479197,"standarderror":0.06021419727521885,"publish":0.09978027433046055,"hello":0.026134797483739598,"find":0.02351830960295959,"sender_name":0.03326009144348685,"name":0.017591727874664828,"email":0.019326945031214716,"stream":0.03326009144348685,"full":0.020744720680542245,"chat":0.0665201828869737,"applicat":0.02156402902853465,"see":0.03326009144348685}},{"label":"Bee assistant","body":"ru.Bee ships with a built-in CLI assistant called bee. It answers questions about the framework directly in your terminal, using a local TF-IDF knowledge base built from the project documentation. Optionally, it routes answers through a local Ollama language model for richer, more conversational responses.\n\nNo external API keys or internet connection are required in the default mode.\n\nBuilding the knowledge base\n\nBefore using the assistant for the first time, generate the knowledge base from the README:\n\nCODE>rubee bee generate # or: rubee bee gen\n\nThis parses the documentation, computes TF-IDF vectors, and writes a bee_knowledge.json file to lib/rubee/cli/. Re-run this command any time the documentation is updated.\n\nInteractive mode\n\nStart an interactive session and ask questions conversationally:\n\nCODE>rubee bee\n\nCODE> ⬡ ⬢ ⬢ ru.Bee — domestic AI assistant\nCODE> ──────────────────────────────────────────────\nCODE> Ask me anything about the ru.Bee framework.\nCODE> Type exit to leave • rubee bee generate to retrain.\nCODE> You: How do I run the server?\n\nType exit, quit, bye, or q to leave the session.\n\nSingle-shot mode\n\nPass a question directly as a command-line argument to get one answer and exit:\n\nCODE>rubee bee how do hooks work\nCODE>rubee bee what databases are supported\nCODE>rubee bee how do I set up JWT authentication\n\nLLM mode\n\nIf you have Ollama installed and running locally, enable LLM mode for more detailed answers. The assistant retrieves the most relevant documentation and passes it as context to the model.\n\nCODE>rubee bee --llm # interactive mode, default model (qwen2.5:1.5b)\nCODE>rubee bee --llm=llama3.2 # interactive mode, specific model\nCODE>rubee bee --llm how do hooks work # single-shot LLM answer\nCODE>rubee bee --llm=qwen2.5:0.5b how do I configure WebSocket # single-shot with specific model\n\nIf the specified model is not available locally, the assistant automatically pulls it from Ollama before answering, displaying a live download progress bar.\n\nEnvironment options\n\nCODE>OLLAMA_URL=http://remote-host:11434 rubee bee --llm # use a custom Ollama endpoint\nCODE>BEE_KNOWLEDGE=/path/to/custom.json rubee bee # use a custom knowledge base file\nCODE>BEE_DEBUG=1 rubee bee --llm # write LLM debug output to /tmp/bee_ollama_debug.txt\n\nSuggestions\n\nAfter every answer, the assistant suggests up to five related topics you might want to explore next, along with a link to the full documentation at https://rubee.dedyn.io/.\n\nCommand reference\n\nCODE>rubee bee generate # build the knowledge base from the README\nCODE>rubee bee gen # alias for generate\nCODE>rubee bee # start interactive mode\nCODE>rubee bee # single-shot answer\nCODE>rubee bee --llm # interactive LLM mode (default model: qwen2.5:1.5b)\nCODE>rubee bee --llm= # interactive LLM mode with a specific Ollama model\nCODE>rubee bee --llm # single-shot LLM answer\nCODE>rubee bee --llm= # single-shot with a specific model\n\nContributing\n\nIf you are interested in contributing to ru.Bee, please read the Contributing guide.\nFeel free to open an issue if you spot one.\nHave an idea or want to discuss something? Open a discussion.","parent":null,"vector":{"assistant":0.16882770566006924,"ship":0.03866887398154717,"built":0.05747304718858165,"cli":0.05747304718858165,"call":0.027342875825855352,"answer":0.2298921887543266,"question":0.07000627795301567,"framework":0.05747304718858165,"direct":0.054685751651710704,"terminal":0.03240225859933015,"local":0.14001255590603134,"idf":0.07000627795301567,"knowledge":0.21269401333558832,"base":0.10226254330342424,"project":0.03038485904794119,"documentate":0.1306782160855657,"optional":0.028736523594290825,"routes":0.022469908212073814,"through":0.03240225859933015,"ollama":0.21269401333558832,"language":0.03866887398154717,"model":0.16066465455156448,"richer":0.03866887398154717,"more":0.054685751651710704,"conversational":0.07000627795301567,"responses":0.035003138976507836,"external":0.03866887398154717,"api":0.03038485904794119,"key":0.024118243665724175,"internet":0.035003138976507836,"connecte":0.03240225859933015,"requir":0.025070788589251495,"default":0.06135752598205455,"mode":0.2507078858925149,"building":0.035003138976507836,"before":0.04651312393736759,"first":0.022469908212073814,"time":0.05227128643422629,"generate":0.09660465924272173,"readme":0.0648045171986603,"code":0.2630039568357128,"gen":0.05227128643422629,"parses":0.035003138976507836,"computes":0.035003138976507836,"vector":0.035003138976507836,"writes":0.035003138976507836,"bee_knowledge":0.0648045171986603,"json":0.04090501732136971,"file":0.04493981642414763,"lib":0.035003138976507836,"command":0.06740972463622144,"any":0.022469908212073814,"updat":0.026135643217113144,"interactive":0.19140013078098747,"start":0.03663072293095148,"session":0.05747304718858165,"ask":0.07000627795301567,"domestic":0.035003138976507836,"anything":0.035003138976507836,"type":0.04215252088727668,"exit":0.09720677579799045,"leave":0.07000627795301567,"retrain":0.035003138976507836,"server":0.02107626044363834,"quit":0.035003138976507836,"bye":0.035003138976507836,"single":0.15681385930267883,"shot":0.18230915428764713,"pas":0.026135643217113144,"queste":0.035003138976507836,"line":0.03038485904794119,"argument":0.028736523594290825,"one":0.04349251381018885,"hook":0.054685751651710704,"work":0.0648045171986603,"databases":0.03038485904794119,"support":0.020452508660684855,"jwt":0.03038485904794119,"authenticat":0.025070788589251495,"llm":0.5165426038150002,"install":0.024118243665724175,"running":0.023256561968683795,"enable":0.035003138976507836,"detail":0.035003138976507836,"retrieves":0.035003138976507836,"most":0.035003138976507836,"relevant":0.035003138976507836,"passes":0.035003138976507836,"context":0.03240225859933015,"qwen2":0.09720677579799045,"llama3":0.035003138976507836,"specific":0.09302624787473518,"configure":0.025070788589251495,"websocket":0.03038485904794119,"specifi":0.035003138976507836,"not":0.022469908212073814,"available":0.025070788589251495,"automatical":0.03240225859933015,"pull":0.035003138976507836,"answering":0.035003138976507836,"displaying":0.035003138976507836,"live":0.035003138976507836,"download":0.035003138976507836,"progres":0.035003138976507836,"bar":0.035003138976507836,"environment":0.024118243665724175,"option":0.023256561968683795,"ollama_url":0.035003138976507836,"url":0.023256561968683795,"http":0.039738055669792265,"remote":0.035003138976507836,"host":0.03240225859933015,"11434":0.035003138976507836,"custom":0.08620957078287246,"endpoint":0.03038485904794119,"path":0.026135643217113144,"bee_debug":0.035003138976507836,"debug":0.09720677579799045,"write":0.026135643217113144,"output":0.028736523594290825,"tmp":0.03038485904794119,"bee_ollama_debug":0.035003138976507836,"txt":0.035003138976507836,"suggestion":0.035003138976507836,"after":0.026135643217113144,"every":0.028736523594290825,"suggest":0.035003138976507836,"five":0.035003138976507836,"relat":0.03038485904794119,"topic":0.035003138976507836,"want":0.05747304718858165,"explore":0.03240225859933015,"next":0.03038485904794119,"along":0.035003138976507836,"link":0.035003138976507836,"full":0.024118243665724175,"dedyn":0.03038485904794119,"reference":0.035003138976507836,"build":0.026135643217113144,"alias":0.03240225859933015,"contributing":0.1050094169295235,"interest":0.035003138976507836,"read":0.028736523594290825,"guide":0.03038485904794119,"feel":0.03038485904794119,"free":0.03038485904794119,"open":0.05747304718858165,"issue":0.03038485904794119,"spot":0.035003138976507836,"idea":0.03240225859933015,"discus":0.035003138976507836,"something":0.03240225859933015,"discussion":0.035003138976507836}},{"label":"Bee assistant — Building the knowledge base","body":"Before using the assistant for the first time, generate the knowledge base from the README:\n\nCODE>rubee bee generate # or: rubee bee gen\n\nThis parses the documentation, computes TF-IDF vectors, and writes a bee_knowledge.json file to lib/rubee/cli/. Re-run this command any time the documentation is updated.","parent":"Bee assistant","vector":{"assistant":0.2570114743110053,"building":0.18650214498517403,"knowledge":0.48568570304364483,"base":0.21794826676005327,"before":0.12391456363531198,"first":0.11972315060041612,"time":0.2785095087517843,"generate":0.20588983378229497,"readme":0.1726442515682711,"code":0.05605303241217167,"gen":0.13925475437589216,"parses":0.18650214498517403,"documentate":0.2785095087517843,"computes":0.18650214498517403,"idf":0.18650214498517403,"vector":0.18650214498517403,"writes":0.18650214498517403,"bee_knowledge":0.1726442515682711,"json":0.10897413338002664,"file":0.11972315060041612,"lib":0.18650214498517403,"cli":0.15311264779279507,"command":0.11972315060041612,"any":0.11972315060041612,"updat":0.13925475437589216}},{"label":"Bee assistant — Interactive mode","body":"Start an interactive session and ask questions conversationally:\n\nCODE>rubee bee\n\nCODE> ⬡ ⬢ ⬢ ru.Bee — domestic AI assistant\nCODE> ──────────────────────────────────────────────\nCODE> Ask me anything about the ru.Bee framework.\nCODE> Type exit to leave • rubee bee generate to retrain.\nCODE> You: How do I run the server?\n\nType exit, quit, bye, or q to leave the session.","parent":"Bee assistant","vector":{"assistant":0.2424993158945365,"interactive":0.2749217055047151,"mode":0.1260383874981365,"start":0.09207682547902608,"session":0.28893427769395136,"ask":0.3519425947266491,"question":0.17597129736332456,"conversational":0.17597129736332456,"code":0.31732798039944626,"domestic":0.17597129736332456,"anything":0.17597129736332456,"framework":0.14446713884697568,"type":0.2119133884720173,"exit":0.32579178039162965,"leave":0.3519425947266491,"generate":0.09713212994807607,"retrain":0.17597129736332456,"server":0.10595669423600865,"quit":0.17597129736332456,"bye":0.17597129736332456}},{"label":"Bee assistant — Single-shot mode","body":"Pass a question directly as a command-line argument to get one answer and exit:\n\nCODE>rubee bee how do hooks work\nCODE>rubee bee what databases are supported\nCODE>rubee bee how do I set up JWT authentication","parent":"Bee assistant","vector":{"assistant":0.19210608521671327,"single":0.2081750301824723,"shot":0.24202078735347848,"mode":0.19969327434988982,"pas":0.2081750301824723,"queste":0.2788062054713289,"direct":0.21779085186608085,"command":0.17897680119779844,"line":0.24202078735347848,"argument":0.22889150333456368,"one":0.17321279028669986,"answer":0.22889150333456368,"exit":0.2580897323192375,"code":0.2513847753318011,"hook":0.21779085186608085,"work":0.2580897323192375,"databases":0.24202078735347848,"support":0.16290785623203946,"jwt":0.24202078735347848,"authenticat":0.19969327434988982}},{"label":"Bee assistant — LLM mode","body":"If you have Ollama installed and running locally, enable LLM mode for more detailed answers. The assistant retrieves the most relevant documentation and passes it as context to the model.\n\nCODE>rubee bee --llm # interactive mode, default model (qwen2.5:1.5b)\nCODE>rubee bee --llm=llama3.2 # interactive mode, specific model\nCODE>rubee bee --llm how do hooks work # single-shot LLM answer\nCODE>rubee bee --llm=qwen2.5:0.5b how do I configure WebSocket # single-shot with specific model\n\nIf the specified model is not available locally, the assistant automatically pulls it from Ollama before answering, displaying a live download progress bar.","parent":"Bee assistant","vector":{"assistant":0.20349939175265605,"llm":0.5982069416430411,"mode":0.28204874281801867,"ollama":0.17091626904086893,"install":0.06783313058421868,"running":0.06540963043688254,"local":0.1968943120369389,"enable":0.09844715601846946,"more":0.07690248478081421,"detail":0.09844715601846946,"answer":0.16164430416450734,"retrieves":0.09844715601846946,"most":0.09844715601846946,"relevant":0.09844715601846946,"documentate":0.0735071145237869,"passes":0.09844715601846946,"context":0.09113211846000266,"model":0.2510406332400145,"code":0.11835277557001958,"interactive":0.15380496956162842,"default":0.05752316420646968,"qwen2":0.18226423692000532,"llama3":0.09844715601846946,"specific":0.13081926087376508,"hook":0.07690248478081421,"work":0.09113211846000266,"single":0.1470142290475738,"shot":0.17091626904086893,"configure":0.07051218570450467,"websocket":0.08545813452043446,"specifi":0.09844715601846946,"not":0.06319714814603788,"available":0.07051218570450467,"automatical":0.09113211846000266,"pull":0.09844715601846946,"before":0.06540963043688254,"answering":0.09844715601846946,"displaying":0.09844715601846946,"live":0.09844715601846946,"download":0.09844715601846946,"progres":0.09844715601846946,"bar":0.09844715601846946}},{"label":"Bee assistant — Environment options","body":"CODE>OLLAMA_URL=http://remote-host:11434 rubee bee --llm # use a custom Ollama endpoint\nCODE>BEE_KNOWLEDGE=/path/to/custom.json rubee bee # use a custom knowledge base file\nCODE>BEE_DEBUG=1 rubee bee --llm # write LLM debug output to /tmp/bee_ollama_debug.txt","parent":"Bee assistant","vector":{"assistant":0.10222942763510648,"environment":0.10222942763510648,"option":0.0985770378544495,"code":0.13377463639092496,"ollama_url":0.1483669753318681,"ollama":0.3863747450639018,"url":0.0985770378544495,"http":0.08421837723258781,"remote":0.1483669753318681,"host":0.13734268533830934,"11434":0.1483669753318681,"llm":0.3863747450639018,"custom":0.3654144638370219,"endpoint":0.12879158168796725,"bee_knowledge":0.13734268533830934,"knowledge":0.2575831633759345,"path":0.11078053128544858,"json":0.08669156357580445,"base":0.08669156357580445,"file":0.09524266722614655,"bee_debug":0.1483669753318681,"debug":0.41202805601492803,"write":0.11078053128544858,"output":0.12180482127900734,"tmp":0.12879158168796725,"bee_ollama_debug":0.1483669753318681,"txt":0.1483669753318681}},{"label":"Bee assistant — Suggestions","body":"After every answer, the assistant suggests up to five related topics you might want to explore next, along with a link to the full documentation at https://rubee.dedyn.io/.","parent":"Bee assistant","vector":{"assistant":0.3564022770631585,"suggestion":0.25862576497049844,"after":0.19310698747784893,"every":0.21232396906329437,"answer":0.21232396906329437,"suggest":0.25862576497049844,"five":0.25862576497049844,"relat":0.22450293443878336,"topic":0.25862576497049844,"want":0.21232396906329437,"explore":0.23940878338505303,"next":0.22450293443878336,"along":0.25862576497049844,"link":0.25862576497049844,"full":0.17820113853157926,"documentate":0.19310698747784893,"http":0.14680519157064484,"dedyn":0.22450293443878336}},{"label":"Bee assistant — Command reference","body":"CODE>rubee bee generate # build the knowledge base from the README\nCODE>rubee bee gen # alias for generate\nCODE>rubee bee # start interactive mode\nCODE>rubee bee # single-shot answer\nCODE>rubee bee --llm # interactive LLM mode (default model: qwen2.5:1.5b)\nCODE>rubee bee --llm= # interactive LLM mode with a specific Ollama model\nCODE>rubee bee --llm # single-shot LLM answer\nCODE>rubee bee --llm= # single-shot with a specific model","parent":"Bee assistant","vector":{"assistant":0.07671544274396518,"command":0.07147240822329352,"reference":0.11133817790503338,"code":0.2677006206151285,"generate":0.12291225360605477,"build":0.08313239838639562,"knowledge":0.0966483275848351,"base":0.06505545258086308,"readme":0.10306528322726555,"gen":0.08313239838639562,"alias":0.10306528322726555,"start":0.05825760297117147,"interactive":0.26091711162054543,"mode":0.23923590870318404,"single":0.2493971951591869,"shot":0.2899449827545053,"answer":0.1828105861283269,"llm":0.6765382930938457,"default":0.06505545258086308,"model":0.17034767370928575,"qwen2":0.10306528322726555,"specific":0.1479492016796878,"ollama":0.0966483275848351}},{"label":"Bee assistant — Contributing","body":"If you are interested in contributing to ru.Bee, please read the Contributing guide.\nFeel free to open an issue if you spot one.\nHave an idea or want to discuss something? Open a discussion.","parent":"Bee assistant","vector":{"assistant":0.14483421900247784,"contributing":0.6305996862660208,"interest":0.21019989542200695,"read":0.1725677876594427,"guide":0.18246632676504207,"feel":0.18246632676504207,"free":0.18246632676504207,"open":0.3451355753188854,"issue":0.18246632676504207,"spot":0.21019989542200695,"one":0.13059002880681037,"idea":0.1945811595236403,"want":0.1725677876594427,"discus":0.21019989542200695,"something":0.1945811595236403,"discussion":0.21019989542200695}},{"label":"Middleware integration","body":"ru.Bee is rack based framework, so you can use register and use middleware for your application.\n1. Create a middleware\n\nCODE># app/inits/middlewares/my_middleware.rb\nCODE>class MyMiddleware\nCODE> def initialize(app)\nCODE> @app = app\nCODE> end\nCODE>\nCODE> def call(env)\nCODE> Logger.info(\"Middleware called\")\nCODE> @app.call(env)\nCODE> end\nCODE>end\n\n2. Register the middleware in the config/base_configuration.rb\n\nCODE># config/base_configuration.rb\nCODE>require_relative 'inits/middlewares/my_middleware'\nCODE>\nCODE>config.middlewares = { middlewares: [MyMiddleware], env: }","parent":null,"vector":{"middleware":0.5713538803324325,"integrate":0.08162198290463321,"rack":0.06315385303664797,"bas":0.0723879179706406,"framework":0.0723879179706406,"register":0.16324396580926642,"applicat":0.06315385303664797,"create":0.04866984084486233,"code":0.3975075577442475,"app":0.2433492042243117,"init":0.13167248926980063,"middlewares":0.32648793161853285,"my_middleware":0.1948154423487323,"clas":0.04385748621052572,"mymiddleware":0.1948154423487323,"def":0.10304061410668407,"initialize":0.06583624463490031,"end":0.1283941172415578,"call":0.20663186824275379,"env":0.1643378597117986,"logger":0.08162198290463321,"info":0.06887728941425125,"config":0.15927465343355504,"base_configurate":0.12630770607329594,"base":0.10304061410668407,"configurate":0.11716755470050436,"require_relative":0.08817365624037352,"require":0.08162198290463321,"relative":0.08817365624037352}}]}
|