I am using Devise and have a database column in my Member model for refer which I want to set before creation when a new member registers. The refer:string needs to store a unique random string that can later be used as a referral code.
The error that I get is: undefined method 'refer=' for #<Member:0x971ece0>
Member model:
class Member < ApplicationRecord
before_create :set_refer
private
def set_refer
self.refer = SecureRandom.urlsafe_base64(8)
end
end
Schema
create_table "members", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin"
t.string "refer"
t.string "referral_code"
t.index ["email"], name: "index_members_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true, using: :btree
end
Any assistance will be greatly appreciated.
Related
In Rails 5, I want to create a new instance of an Author model, but in the process I want to copy only a subset of the attribute values (columns) from my User model.
I am trying to run the following code:
user = User.first
Author.create user.attributes.without("id", "token", "secret", "created_at", "updated_at", "active", "email", "encrypted_password", "first_name", "last_name", "reset_password_token", "reset_password_sent_at", "remember_created_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip")
The User.first method works and returns a valid user from the table. However, the Author.create line doesn't work. I'm getting a NoMethodError: undefined method `each' for nil:NilClass error.
Here is my User table from the schema.rb file:
create_table "users", force: :cascade do |t|
t.string "provider", null: false
t.string "uid", null: false
t.string "name"
t.string "location"
t.string "image_url"
t.string "url"
t.string "token"
t.string "secret"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "active", default: false
t.text "description"
t.string "screen_name"
t.integer "followers"
t.integer "following"
t.integer "statuses"
t.integer "listed"
t.integer "lists"
t.integer "favorites"
t.integer "views", default: 0
t.string "website"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "first_name", default: "", null: false
t.string "last_name", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.index ["active"], name: "index_users_on_active", using: :btree
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["provider", "uid"], name: "index_users_on_provider_and_uid", unique: true, using: :btree
t.index ["provider"], name: "index_users_on_provider", using: :btree
t.index ["uid"], name: "index_users_on_uid", using: :btree
end
And here is my Author table:
create_table "authors", force: :cascade do |t|
t.string "uid", null: false
t.string "provider", null: false
t.string "name"
t.string "location"
t.string "image_url"
t.string "url"
t.text "description"
t.string "screen_name"
t.integer "followers", default: 0
t.integer "following", default: 0
t.integer "statuses", default: 0
t.integer "listed", default: 0
t.integer "lists", default: 0
t.integer "favorites", default: 0
t.integer "views", default: 0
t.string "website"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["provider"], name: "index_authors_on_provider", using: :btree
t.index ["uid", "provider"], name: "index_authors_on_uid_and_provider", unique: true, using: :btree
t.index ["uid"], name: "index_authors_on_uid", using: :btree
end
As you can see, the new Author table has many of the same columns/attributes as the User table, but I only want to copy across a subset of the User attributes (columns and values) when creating the new Author object.
Maybe the user.attributes.without method isn't the right one?
You can do it via slice since user.attributes is just a hash of values.
user.attributes.slice('name', 'location')
I'm trying to get all Activities related to users of the same school (a string on the user object), but the error I'm getting is this:
Can't join 'Activity' to association named 'users'; perhaps you
misspelled it?
activity_controller.rb
#school = current_user.school
#bathroom = Activity.includes(:users).where(name: 'Bathroom').where( :user => { :school => #school} )
and the schema:
create_table "activities", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "student_id"
t.string "status"
t.integer "user_id"
t.index ["student_id"], name: "index_activities_on_student_id"
t.index ["user_id"], name: "index_activities_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name"
t.string "grade"
t.string "school"
t.integer "maxout"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Not users but user because Activity belongs to User
#bathroom = Activity.includes(:user).where(name: 'Bathroom').where( :users => { :school => #school} )
But User has many activities so User.includes(:activities)
Of course, you have to provide associations:
class Activity
belongs_to :user
class User
has_many :activities
I have a model called room and in the show view I want to display other rooms nearby.
show.html.erb
<div>
<% for room in #room.nearbys(10) %>
<%= image_tag room.photos[0].image.url(:medium) %>
<%= link_to room.listing_name, room %><br>
(<%= room.distance.round(2) %> miles away)
<% end %>
</div>
schema.rb
ActiveRecord::Schema.define(version: 20161006135631) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_id", null: false
t.string "resource_type", null: false
t.string "author_type"
t.integer "author_id"
t.datetime "created_at"
t.datetime "updated_at"
t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id", using: :btree
t.index ["namespace"], name: "index_active_admin_comments_on_namespace", using: :btree
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id", using: :btree
end
create_table "admin_users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_admin_users_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true, using: :btree
end
create_table "photos", force: :cascade do |t|
t.integer "room_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.index ["room_id"], name: "index_photos_on_room_id", using: :btree
end
create_table "rooms", force: :cascade do |t|
t.string "listing_name"
t.string "accommodation_type"
t.integer "persons"
t.integer "property"
t.integer "living_area"
t.text "rooms_total"
t.text "features_short"
t.string "pets"
t.string "smoking"
t.string "check_in"
t.string "check_out"
t.string "location"
t.text "distance"
t.text "features_long"
t.text "detailed_description"
t.text "house_rules"
t.string "address"
t.text "video"
t.integer "nightly_price"
t.integer "hourly_price"
t.text "detailed_price"
t.boolean "active"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "latitude"
t.float "longitude"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "firstname"
t.string "lastname"
t.string "provider"
t.string "uid"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
add_foreign_key "photos", "rooms"
end
I have used the RailsCasts Episode for orientation.
Unfortunately I am getting this Error:
How can I make this work?
Any hints for a solution are very appreciated!
Your rooms table have column distance.
And your SQL query is creating an alias distance.(AS DISTANCE).
Hence PostgreS is raising ambiguous column error.
This query is generated by gem which you are using I recommend you to change the column name of column distance to something else like my_distance or something which will not conflict with the query generated by gem.
I deployed my rails app to Heroku. I am trying to use the Heroku console to add categories to my app but I do not know the commands.
Controller:
class PortfolioController < ApplicationController
def index
#posts = Post.all.order("created_at DESC")
end
def about
end
def portfolio
end
def contact
end
def webapp
category = Category.find_by_category('webapp')
#posts = Post.where(category_id: category.id)
end
def art
category = Category.find_by_category('gameart')
#posts = Post.where(category_id: category.id)
end
end
Schema:
ActiveRecord::Schema.define(version: 20160910220215) do
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "admins", ["email"], name: "index_admins_on_email", unique: true
add_index "admins", ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
create_table "categories", force: :cascade do |t|
t.string "category"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "category_id"
end
end
To create a category in the rails/heroku console under your table Categories simply run:
Category.connection
Then:
Category.create(name: "NAME_OF_CATEGORY")
It will then create a category as such:
#<Category id: 1, name: "NAME_OF_CATEGORY", created_at: "2016-09-14 22:25:14", updated_at: "2016-09-14 22:25:14">
I have 3 models, User, member_role & member. I need to use after_create callback on User model and populate the member model fetching the role from member_role model.
Would appreciate any help regarding how I can accomplish that.
My Member_role model loos like
1 - admin
2 - teacher
3- student
4 - so on
And mr member Model looks like
member_id
user_id
member_role_id
Need to populate Member model with an after_create callback on User model.
Here is my Schema.rb
ActiveRecord::Schema.define(version: 20150930061155) do
create_table "member_roles", force: :cascade do |t|
t.string "role", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "members", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id", limit: 4
t.integer "member_role_id", limit: 4
end
create_table "users", force: :cascade do |t|
t.string "provider", limit: 255, default: "email", null: false
t.string "uid", limit: 255, default: "", null: false
t.string "encrypted_password", limit: 255, default: "", null: false
t.string "reset_password_token", limit: 255
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", limit: 4, default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip", limit: 255
t.string "last_sign_in_ip", limit: 255
t.string "confirmation_token", limit: 255
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email", limit: 255
t.string "name", limit: 255
t.string "nickname", limit: 255
t.string "image", limit: 255
t.string "email", limit: 255
t.text "tokens", limit: 65535
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", using: :btree
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
add_index "users", ["uid", "provider"], name: "index_users_on_uid_and_provider", unique: true, using: :btree
end
Assuming the default MemberRole is the first one:
class User
after_create :assign_member_role
private
def assign_member_role
mr = MemberRole.first # default MR
Member.create!(user_id: self.id, member_role_id: mr.id)
end
end