Ruby on Rails: Variables in Functions - ruby-on-rails

I wondering if I can somehow make "stat" a variable in the following function:
def stats(stat)
self.items.sum(:stat) + self.stat
end
I'm wondering how to make :stat in self.items.sum(:stat) a variable. I'm not sure about the syntax.
Sorry if this is a horribly newbish question.
Items migration:
class CreateItems < ActiveRecord::Migration
def change
create_table :items do |t|
t.string :title
t.text :content
t.integer :price
t.integer :strength
t.integer :agility
t.integer :intellect
t.integer :will
t.integer :perception
t.integer :hearm
t.integer :laarm
t.integer :raarm
t.integer :charm
t.integer :llarm
t.integer :rlarm
t.integer :damage
t.integer :hardpoints
t.timestamps
end
end
end
Characters migration:
class CreateCharacters < ActiveRecord::Migration
def change
create_table :characters do |t|
t.string :name
t.text :bio
t.integer :strength
t.integer :agility
t.integer :intellect
t.integer :will
t.integer :perception
t.integer :hearm
t.integer :laarm
t.integer :raarm
t.integer :charm
t.integer :llarm
t.integer :rlarm
t.integer :currency
t.integer :user_id
t.timestamps
end
end
end

I'm sure what you want to
def stats(stat)
stat = stat.to_sym
items.sum(stat) + read_attribute(stat)
end
stat = stat.to_sym is just to ensure it's a symbol, so you can pass a string and it will still work, but it's not need if you only pass symbols.
so you you should call it as
character.stats(:strength) or character.stats('strength')

Related

rails add created_at for the column value

I am trying to add created at for a value in a column
for example if I added a new invoice it will show me the date that I add the invoice not the date I add the case
<%= #case.invoice.created_at %>
This gives me null
in my database
class AddAttachmentInvoiceToCases < ActiveRecord::Migration
def self.up
change_table :cases do |t|
t.attachment :invoice
end
end
def self.down
remove_attachment :cases, :invoice
end
end
in my schema
create_table "cases", force: :cascade do |t|
t.string "pt_first_name"
t.string "pt_last_name"
t.date "date_received"
t.date "due_date"
t.string "shade"
t.string "mould"
t.string "upper_lower"
t.integer "user_id"
t.string "invoice_file_name"
t.string "invoice_content_type"
t.integer "invoice_file_size", limit: 8
t.datetime "invoice_updated_at"
t.string "implant_brand"
t.string "implant_quantity"
t.integer "number"
t.boolean "finished"
t.boolean "ship"
t.boolean "outsourced"
t.string "invoice2_file_name"
t.string "invoice2_content_type"
t.integer "invoice2_file_size", limit: 8
t.datetime "invoice2_updated_at"
t.string "invoice3_file_name"
t.string "invoice3_content_type"
t.integer "invoice3_file_size", limit: 8
t.datetime "invoice3_updated_at"
t.string "invoice4_file_name"
t.string "invoice4_content_type"
t.integer "invoice4_file_size", limit: 8
t.datetime "invoice4_updated_at"
t.string "invoice5_file_name"
t.string "invoice5_content_type"
t.integer "invoice5_file_size", limit: 8
t.datetime "invoice5_updated_at"
t.datetime "created_at"
t.datetime "updated_at"
end
In the migration for the Invoice do you have t.timestamps?
For example:
class CreateInvoices < ActiveRecord::Migration
def change
create_table :invoices do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
If not you may need to add those
class AddTimestampsToInvoice < ActiveRecord::Migration
def change
add_column :invoices, :created_at, :datetime, null: false
add_column :invoices, :updated_at, :datetime, null: false
end
end

How to show multiple ids to a table in rails

I am making a Band application where a Venue has many Events and Bands through Events.
I realized that in my form for creating an event can only hold one band_id
but I want to have many bands because it only makes sense to do so.
This is my Schema
ActiveRecord::Schema.define(version: 20170817180728) do
create_table "bands", force: :cascade do |t|
t.string "name"
t.string "genre"
t.string "image"
t.boolean "explicit_lyrics"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "events", force: :cascade do |t|
t.string "name"
t.text "date"
t.boolean "alcohol_served"
t.string "image"
t.integer "venue_id"
t.integer "band_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "venues", force: :cascade do |t|
t.string "name"
t.string "city"
t.string "state"
t.boolean "family_friendly"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
These are my models
class Venue < ApplicationRecord
has_many :events
has_many :bands, through: :events
end
class Event < ApplicationRecord
belongs_to :venue
belongs_to :band
end
class Band < ApplicationRecord
has_many :events
end
I am fairly new to rails this is a practice web app. I want to be able to be able to show multiple band_ids to my event.
Would I just keep repeating t.band_id in my form??
You'll want to specify a foreign key relationship in your migration that reflects the Active Record associations you've set up in your models using belongs_to instead of a data type. This way, you'll get a references from one table to another, or in your case, from one table to two others, which is how one table with two one-to-many relationships is set up.
class CreateEvents < ActiveRecord::Migration
def change
create_table :venues do |t|
t.string :name
t.string :city
t.string :state
t.boolean :family_friendly
t.string :image
t.timestamps
end
create_table :bands do |t|
t.string :name
t.string :genre
t.string :image
t.boolean :explicit_lyrics
t.timestamps
end
create_table :events do |t|
t.belongs_to :venue, index: true # Look here!
t.belongs_to :band, index: true # and here!
t.string :name
t.text :date
t.boolean :alcohol_served
t.string :image
t.timestamps
end
end
end

Rails 4 set the default value of a existing column to zero

The question can't be explained more.
db/migrate/20140415150026_create_poll_answers.rb
class CreatePollAnswers < ActiveRecord::Migration
def change
create_table :poll_answers do |t|
t.string :content
t.integer :counter
t.boolean :instant_value
t.timestamps
end
end
end
db/schema
create_table "poll_answers", force: true do |t|
t.string "content"
t.integer "counter"
t.boolean "instant_value"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "poll_question_id"
end
I found an answer to this but I am not sure it works for rails 4 and I also don't know where I should write it !!!
add_column :Table_name, :colman_name, :data_type, :default => "default"
You can simply set defaults like this for new migrations:
create_table :poll_answers, force: true do |t|
t.string :content, default: 'no_text'
t.integer :counter, default: 0
t.float :money_in_pocket, default: 0.0
end
Or you can change existing migrations like this:
def change
change_column :poll_answers, :counter, :integer, default: 100
end
Or even shorter:
change_column_default(:poll_answers, :counter, 3000)

Rails schema not changing

I'm trying to change a column called "description" in my table called "posts" to a .text rather than a .string so I can avoid getting errors for the value being too long.
I generated a new migration and ran rake db:migrate after having this:
class ChangePostsFormatInMyTable < ActiveRecord::Migration
def self.up
change_column :posts, :description, :text, :limit => nil
end
def self.down
change_column :posts, :description, :string
end
end
But the schema file doesn't show any changes and my column won't change. Am I missing something?
Schema:
ActiveRecord::Schema.define(version: 20140125221803) do
create_table "posts", force: true do |t|
t.string "description"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "title"
t.string "image"
end
end

rails 3.2 migration cannot add index to create_table in change method

here is my migration in rails 3.2.2:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
t.index [:name, :item_id]
end
end
end
and here is the migrate error:
== CreateStatistics: migrating ===============================================
-- create_table(:statistics)
ActiveRecord::ConnectionAdapters::TableDefinition
rake aborted!
An error has occurred, all later migrations canceled:
undefined method `index' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0xbd16888>
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
what is the right way to create a index?
You can still add an index as a part of a "change" migration. You just have to do it outside of the call to create_table:
class CreateStatistics < ActiveRecord::Migration
def change
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
end
This correctly creates the table and then the index on an "up" migration and drops the index and then the table on a "down" migration.
so I change it to the old way, and it works.
and I think there is a new way doing this by using change method.
class CreateStatistics < ActiveRecord::Migration
def up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, [:name, :item_id]
end
def down
drop_table :statistics
end
end
If you have more than one index and don't want to repeat the table name several times in individual add_index calls, you can use a change_table block that follows the create_table.
create_table :user_states do |t|
t.references :user, :null => false
t.integer :rank
t.integer :status_code
end
change_table :user_states do |t|
t.index [:rank, :status_code]
end
class CreateTempPfp < ActiveRecord::Migration
def change
create_table :temp_ptps do |t|
t.string :owner
t.integer :source_id
t.string :source_type
t.integer :year
t.string :pcb_type
t.float :january
t.float :february
t.float :march
t.float :april
t.float :may
t.float :june
t.float :july
t.float :august
t.float :september
t.float :october
t.float :november
t.float :december
t.float :dollar_per_sqft
t.float :dollar_per_unit
t.integer :rp_acc_code
t.integer :rp_property_id
t.integer :real_estate_property_id
t.timestamps
end
add_index :temp_ptps, [:source_id, :source_type]
end
end
It looks like create_table yields an ActiveRecord::ConnectionAdapters::TableDefinition class. This class does not contain the method index. Instead, change_table appears to yield an ActiveRecord::ConnectionAdapters::Table class which includes this index method.
If you want to add an index during a create_table migration, try this:
class CreateStatistics < ActiveRecord::Migration
def self.up
create_table :statistics do |t|
t.string :name
t.integer :item_id
t.integer :value
t.text :desc
t.timestamps
end
add_index :statistics, :name
add_index :statistics, :item_id
end
def self.down
drop_table :statistics
end
end

Resources