Rails 4 set the default value of a existing column to zero - ruby-on-rails

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)

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

Rails NoMethodError: undefined method `name' for "#<RecipeType:0x000055cd000b18a0>":String

I've been having trouble to do a challenge with Active Records, I read the documentation, and seen other examples with belongs_to that I remade and worked, I have no clue anymore about what I'm doing wrong here when I try to call recipe.recipe_type.name I get the error Rails NoMethodError: undefined method `name' for "#":String
schema.rb
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipe_types_on_recipe_type_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
end
end
migrations
def change
create_table :recipes do |t|
t.string :title
t.string :cuisine
t.string :difficulty
t.integer :cook_time
t.timestamps
end
end
end
class AddFieldsToRecipe < ActiveRecord::Migration[5.2]
def change
add_column :recipes, :ingredients, :text
add_column :recipes, :cook_method, :text
end
end
class CreateRecipeTypes < ActiveRecord::Migration[5.2]
def change
create_table :recipe_types do |t|
t.string :name
t.timestamps
end
end
end
class AddRecipeRefToRecipeType < ActiveRecord::Migration[5.2]
def change
add_reference :recipe_types, :recipe_type, foreign_key: true
end
end
You seemed to have added the recipe_type reference to the wrong table. Your last migration should probably have been
add_reference :recipes, :recipe_type, foreign_key: true
because as it is, you have added the reference_type reference to ReferenceType.
So the final schema was:
ActiveRecord::Schema.define(version: 2020_03_26_013134) do
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["recipe_id"], name: "index_recipe_types_on_recipe_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipes_on_recipe_type_id"
end
end
and with
models/recipe_type
class RecipeType < ApplicationRecord
has_many :recipes
end
models/recipe
class Recipe < ApplicationRecord
belongs_to :recipe_type
end
You can start a simple has_many belongs_to active record association, I hope this helps as many people as those who helped me, in the beginning of this journey, strongly recommend to study db:migrate, db:rollback, db:create and db:drop for those who encounter some trouble.

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

Ruby on Rails: Variables in Functions

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')

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