Here is my schema:
create_table :policies do |t|
t.string :name
t.timestamps
end
create_table :permissions do |t|
t.string :name
t.string :method
t.string :controller
t.timestamps
end
create_join_table :policies, :permissions do |t|
t.index :policy_id
t.index :permission_id
end
And here is the code I am using to create the records and their associations:
policy = Policy.create! name: "View All"
permission = Permission.create!({
name: "View Events",
method: "index",
controller: "Events"
})
policy.permissions << permission
And its returning the following error:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "permission_policies" does not exist
The table name that was created through the migration is policies_permissions
I wonder if this is an issue with the class names not being inferred properly
Swap the positions of permissions and policies in the migration so that you create permissions_policies instead of policies_permissions. Rails infers the class names for a join table in alphabetical order.
See this answer for more information on join table naming conventions.
I'm new to Ruby on Rails and would be grateful for some help with migrations.
Version 4
first migration
class CreateRooms < ActiveRecord::Migration
def change
create_table :rooms do |t|
t.integer :legacy_id, null: true
t.string :tag, null: false
t.string :name_en, null: false
t.string :name_et, null: false
t.string :name_ru, null: false
t.string :color, default: 'Black'
t.timestamp :enabled_from, default: 0
t.timestamp :enabled_to, default: 0
t.timestamps null: false
end
add_index :rooms, :tag, unique: true
add_index :rooms, :name_en, unique: true
add_index :rooms, :name_et, unique: true
add_index :rooms, :name_ru, unique: true
end
end
next one
class AddDefaultValuesToRoom < ActiveRecord::Migration
def change
add_column :rooms, :priority, :integer, null: false
change_column :rooms, :enabled_from, :datetime, default: '2008-08-15'
change_column :rooms, :enabled_to, :datetime, default: '2050-12-31'
add_index :rooms, :priority, unique: true
end
end
Strangely enough this is not reflected in schema
create_table "rooms", force: :cascade do |t|
t.integer "legacy_id"
t.string "tag", null: false
t.string "name_en", null: false
t.string "name_et", null: false
t.string "name_ru", null: false
t.string "color", default: "Black"
t.datetime "enabled_from", default: '2008-08-15 00:00:00'
t.datetime "enabled_to", default: '2050-12-31 00:00:00'
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "rooms", ["name_en"], name: "index_rooms_on_name_en", unique: true
add_index "rooms", ["name_et"], name: "index_rooms_on_name_et", unique: true
add_index "rooms", ["name_ru"], name: "index_rooms_on_name_ru", unique: true
add_index "rooms", ["tag"], name: "index_rooms_on_tag", unique: true
rake db:rollback crashes
rake db:rollback STEP=2 --trace
** Invoke db:rollback (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:rollback
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Migrating to AddDefaultValuesToRoom (20160127121254)
(0.1ms) begin transaction
== 20160127121254 AddDefaultValuesToRoom: reverting ===========================
(0.1ms) rollback transaction
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
ActiveRecord::IrreversibleMigration/usr/local/rvm/gems/ruby-2.2.1/gems/activerecord-4.2.2/lib/active_record/migration/command_recorder.rb:65:in `inverse_of'
Now I'm in a fix, could somebody help me out ?
TIA
Pavel
change_column creates an irreversible change to your database, which means you can't roll it back. See the guide: http://guides.rubyonrails.org/active_record_migrations.html#changing-columns
The idea here is that reverting your data would result in data loss, so Rails prevents you from doing something destructive by default and throws an error to stop the process.
Change your last migration to utilize reversible or up/down methods, in order to explicitly tell Rails how to reverse your change (note that you will lose any data stored in the new column priority). See: http://guides.rubyonrails.org/active_record_migrations.html#using-reversible
Here's an example using up/down methods:
class AddDefaultValuesToRoom < ActiveRecord::Migration
def up
add_column :rooms, :priority, :integer, null: false
change_column :rooms, :enabled_from, :datetime, default: '2008-08-15'
change_column :rooms, :enabled_to, :datetime, default: '2050-12-31'
add_index :rooms, :priority, unique: true
end
def down
remove_column :rooms, :priority
change_column :rooms, :enabled_from, :datetime, default: 0
change_column :rooms, :enabled_to, :datetime, default: 0
end
end
I'm having trouble defining an amount for a pay action in my item controller. I'm trying to pull in the item price stored in the db. I've tried everything. I reread this, http://guides.rubyonrails.org/action_controller_overview.html, and still no luck.
In items controller:
def pay
# Find the user to pay.
user = User.find( params[:id] )
amount = #I have no idea what to put here
fee = 100
If I put in a number it works fine. However when I try to access the item price that is stored in the db, that is when things blow up.
I've tried various definitions:
#item.price #fail
item_price #fail
Item.find (params: [:price]) #fail
Item.price #fail
#EVERYTHING FAILS
Schema:
ActiveRecord::Schema.define(version: 20150127171203) do
create_table "items", force: true do |t|
t.string "name"
t.decimal "price"
t.text "description"
t.integer "booth_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "category_id"
t.integer "user_id"
t.string "image"
t.string "image_two"
end
create_table "users", force: true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.string "activation_digest"
t.boolean "activated", default: false
t.datetime "activated_at"
t.string "reset_digest"
t.datetime "reset_sent_at"
t.boolean "admin", default: false
t.string "avatar"
t.text "about"
t.string "location"
t.string "publishable_key"
t.string "secret_key"
t.string "stripe_user_id"
t.string "currency"
end
(edit) I also tried defining items in the pay action and that did not help either. 'item = Item.find ( params[:id]'
Does anyone know the right way to do this? I feel like this should be easy but I'm having trouble with it.
Thanks for your consideration and help!
How is a user related to an item? I ask this because if you are using active record, the associations you make in your database will determine the methods that are created for you. Does a user has_many items in your model? Does an item belong_to a user? In which case would be
#user = User.find(1)
and you could find the price like
#item = #user.items.find(1)
#price = #item.price
EDIT
Ok, I took a look at the code you provided here. This example shows a pay method defining a route in the users controller which seems to only be setup to accept a one time fee. In the comments above it, it even says make a one-off payment so we know this is true.
Even in this example here they explicitly say it's for a fixed amount. Now how do we make it dynamic? Well, look at the code. There's some logic in the pay controller isn't there?
You see that Stripe::Charge object being created?
charge = Stripe::Charge.create(
{
amount: amount,
currency: user.currency,
card: params[:token],
description: "Test Charge via Stripe Connect",
application_fee: fee
},
# Use the user-to-be-paid's access token
# to make the charge.
user.secret_key
)
You can move this logic into your item MODEL. Call it pay or something as long as it takes in the user as a parameter.
def pay(user)
amount = self.price
begin
charge = Stripe::Charge.create(
{
amount: amount,
currency: user.currency,
card: user.token,
description: "Test Charge via Stripe Connect",
application_fee: fee
},
# Use the user-to-be-paid's access token
# to make the charge.
user.secret_key
)
flash[:notice] = "Charged successfully! <a target='_blank' rel='connected-account' href='https://dashboard.stripe.com/test/payments/#{charge.id}'>View in dashboard ยป</a>"
rescue Stripe::CardError => e
error = e.json_body[:error][:message]
flash[:error] = "Charge failed! #{error}"
end
end
Then somewhere in your items CONTROLLER define the pay method instead of users like you had before(Make sure you change your routes accordingly). Then call the pay method you just defined, this way you have the price and you can find the user that is currently logged in.
def pay
user = User.find(session[:user_id])
item = Item.find(params[:id])
item.pay(user)
redirect "somewhere"
end
I am using Rails 4.1.1 and pg (0.17.1) gem I having error while running the migration
ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR: column "page_ids" is of type integer[] but default expression is of type integer
here is my migration code
class CreatePages < ActiveRecord::Migration
def change
create_table :pages do |t|
t.string :name
t.integer :page_ids, array: true, null: false, default: '{}'
t.timestamps
end
end
end
the array: true not working
Try:
t.integer :page_ids, array: true, null: false, default: []
when trying to run migration to add a spatial index, get
Unknown key: spatial/Users/ME/.rvm/gems/ruby-2.0.0-p353/gems/activesupport-4.0.2/lib/active_support/core_ext/hash/keys.rb:70:in `block in assert_valid_keys'
Using
Ruby 2.0.353
Rails 4.0.2
RGEO 0.3.20
RGEO Active Record 0.4.6
List item
activerecord-mysql2spatial-adapter 0.4.3
Migration Index file looks like
class CreateAddresses < ActiveRecord::Migration
def change
create_table :addresses, :options => 'ENGINE=MyISAM' do |t|
t.string :street_1
t.string :street2
t.string :city
t.string :state
t.string :zip
t.string :country
t.string :full_address
t.column :latlon, :point, :null => false
t.timestamps
end
add_index :addresses, :latlon, :spatial => true
end
end
UPDATE
Corrected this and other errors when I changed the adapter in my database.yml file from mysql2 to mysql2spatial