Rails truncates hash on save: - ruby-on-rails

I have a rails model with a hashed password field in it (surprise, surprise), which after some manipulation, is 40 characters long. I generate a user in script/console and it appears as follows:
#<User id: 1, firstname: "true", lastname: "false", username: "chaines51", hashed_password: "2Gr0GWvPunB3x5jomRTSTZJRIelC2RW103d7f3db">
I then run user_instance.save, which returns true, and the user then looks like this:
#<User id: 1, firstname: "true", lastname: "false", username: "chaines51", hashed_password: "103d7f3db">
Any idea what is happening to the other 30+ characters? I changed the field in the migration from string to text, but it still gets truncated
EDIT: The model code is:
require 'digest/sha1'
class User < ActiveRecord::Base
validates_presence_of :username, :password, :password_confirmation, :firstname, :lastname
validates_length_of :username, :within => 3..40
validates_length_of :password, :within => 5..40
validates_uniqueness_of :username
validates_confirmation_of :password
belongs_to :school
attr_protected :id, :salt
attr_accessor :password, :password_confirmation
def self.random_string(len)
#generate a random salt consisting of digits and letters.
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
salt = ""
1.upto(len) { |i| salt << chars[rand(chars.size-1)] }
return salt
end
def password=(pass)
#password=pass
#salt = User.random_string(40-pass.length)
self.hashed_password = User.encrypt(#password, #salt)
end
def self.encrypt(pass, salt)
hash = Digest::SHA1.hexdigest(pass+salt)
hash.slice!(0..(40-pass.length-1))
hash = salt+hash;
end
def self.checkhash(pass, hash)
salt = hash.slice!(0..40-pass.length-1)
rehash = User.encrypt(pass, salt)
return rehash == (salt+hash)
end
def self.authenticate(login, pass)
u = User.find_by_username(login)
return nil if u.nil?
return u if User.checkhash(pass, u.hashed_password)
nil
end
end
and the db/schema.rb is:
ActiveRecord::Schema.define(:version => 20100127034504) do
create_table "categories", :force => true do |t|
t.string "title"
end
create_table "questions", :force => true do |t|
t.string "question"
t.string "a"
t.string "b"
t.string "c"
t.string "d"
t.string "e"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "questions_quizzes", :id => false, :force => true do |t|
t.integer "app_id"
t.integer "category_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "quizzes", :force => true do |t|
t.string "title"
t.integer "category_id"
end
create_table "schools", :force => true do |t|
t.string "name"
t.integer "coach_id"
end
create_table "users", :force => true do |t|
t.string "firstname", :null => false
t.string "lastname", :null => false
t.string "username", :null => false
t.boolean "needs_pass", :default => false
t.integer "school_id"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "confirmed", :default => false
t.text "hashed_password"
end
end

Showing the model code, and the table info form db/schema.rb, would be really helpful. Right off, I can tell you that a string column will hold up to 255 characters without a problem, so there might be something else at fault. If something is restricting, it will most likely show itself in one of the two places I named above.

Related

Why is my controller not saving my object in the database?

I am saving an entry object for CalendarEntry which is my model, but in the view when I click "Done" for some reason the object doesn't save.
In my point of view my controller is fine, but maybe the issue is there:
Controller
def create
#entry = CalendarEntry.new(entries_params)
binding.pry
if #entry.save
render 'admins/calendar_entries/index'
else
render 'admins/calendar_entries/new'
end
end
def entries_params
conversions
params.require(:calendar_entry).permit(:entry_type, :entry_level, :visible, :title, :publication_date, :expiration_date, :content, :phonenumber, :website, :state, :city, :address)
end
def conversions
params[:calendar_entry][:entry_type] = params[:calendar_entry][:entry_type].to_i
params[:calendar_entry][:entry_level] = params[:calendar_entry][:entry_level].to_i
end
Console
As you see in the console is asking me for two values "calendar_categories" and "calendar_entry_categories", but how it's supposed to ask it because my "CalendarEntry" only ask for the values in there,
P.D. The id, created_at and updated_at is generated automatically.
Update July/17 - 11:12pm
Schema defined here:
create_table "calendar_categories", force: :cascade do |t|
t.string "name"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "calendar_entries", force: :cascade do |t|
t.integer "entry_type"
t.integer "entry_level"
t.boolean "visible"
t.string "title"
t.datetime "publication_date"
t.datetime "expiration_date"
t.text "content"
t.string "phonenumber"
t.string "website"
t.string "state"
t.string "city"
t.string "address"
t.string "profile_picture"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "calendar_entry_categories", force: :cascade do |t|
t.bigint "calendar_entry_id"
t.bigint "calendar_category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["calendar_category_id"], name: "index_calendar_entry_categories_on_calendar_category_id"
t.index ["calendar_entry_id"], name: "index_calendar_entry_categories_on_calendar_entry_id"
end
Model defined here:
class CalendarEntry < ApplicationRecord
scope :visible, -> { where(visible: true) }
scope :invisible, -> { where(visible: false) }
scope :expired, -> { where('expiration_date < ?', Time.zone.now) }
scope :active, -> { where('expiration_date >= ?', Time.zone.now) }
has_many :calendar_entry_categories, dependent: :destroy
has_many :calendar_categories, through: :calendar_entry_categories
enum entry_type: %i[event program]
enum entry_level: %i[municipal statal federal injuve]
mount_uploader :profile_picture, CalendarEntryProfilePictureUploader
validates :entry_type, :entry_level, :visible, :title,
:expiration_date, :content, :phonenumber, :website, :state, :city,
:address, :calendar_categories,
:calendar_entry_categories, presence: true
validates :publication_date, presence: true, on: :update
validates :title, uniqueness: true
validates :phonenumber, numericality: { only_integer: true }
validates :phonenumber, length: { is: 10 }
validates_inclusion_of :entry_type, in: CalendarEntry.entry_types
validates_inclusion_of :entry_level, in: CalendarEntry.entry_levels
validate :expiration_date_range
before_validation :init, on: :create
private
def init
self.publication_date ||= Time.zone.now
end
def expiration_date_range
return if !expiration_date.nil? && expiration_date > publication_date
errors.add(:expiration_date, :past_expiration_date)
end
end
It looks like you're trying to validate the presence of calendar_categories and calendar_entry_categories in your model validations.
You won't be able to validate their presence, considering a CalendarEntryCategory cannot exist until a CalendarEntry exists, and a CalendarCategory might not always exist when a CalendarEntry is created.
Therefore, to get this to work, all you should have to do is remove
:calendar_categories, :calendar_entry_categories from the presence: true validations in your CalendarEntry model.

Ruby / Rails - Paperclip::Error in ModificationsController#create

Paperclip::Error in ModificationsController#create Modification model missing required attr_accessor for 'image_file_name'
Error:
Model: modification.rb
class Modification < ActiveRecord::Base
has_attached_file :image,
styles: { thumb: ["64x64#", :jpg],
original: ['500x500>', :jpg] },
convert_options: { thumb: "-quality 75 -strip",
original: "-quality 85 -strip" }
validates_attachment :image,
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
end
Controller: modifications_controller.rb
class ModificationsController < ApplicationController
def index
#modifications = Modification.order('created_at')
end
def new
#modifications = Modification.new
end
def create
#modifications = Modification.new(modification_params)
if #modifications.save
flash[:success] = "Modification contributed!"
redirect_to collection_path
else
render 'new'
end
end
private
def modification_params
params.require(:modification).permit(:image, :title)
end
end
Migration: _create_modifications.rb
class CreateModifications < ActiveRecord::Migration
def change
create_table :modifications do |t|
t.string :title
t.string :image_file_name
t.string :image_content_type
t.integer :image_file_size
t.timestamps null: false
end
end
end
Migration: _add_attachment_modification_to_profiles.rb
class AddAttachmentModificationToProfiles < ActiveRecord::Migration
def self.up
change_table :profiles do |t|
t.attachment :modification
end
end
def self.down
remove_attachment :profiles, :modification
end
end
Schema.rb
create_table "modifications", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
...
create_table "profiles", force: :cascade do |t|
t.integer "user_id"
t.string "first_name"
t.string "last_name"
t.string "location"
t.string "modifications"
t.string "website"
t.text "bio"
t.datetime "created_at"
t.datetime "updated_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "modification_file_name"
t.string "modification_content_type"
t.integer "modification_file_size"
t.datetime "modification_updated_at"
end
You declared twice has_attached_file :image method in your Model: modification.rb
Try to delete very first one has_attached_file :image and let me know if that works for you.

Category(#69942071276340) expected, got String(#8940340)

I'm trying to submit a form for my rails app but I'm getting the error in the title and I'm not entirely sure how to fix it. Category is my foreign key.
= form_for #menu_price do |f|
- if #menu_price.errors.any?
#error_explanation
h2 = "#{pluralize(#menu_price.errors.count, "error")} prohibited this menu_price from being saved:"
ul
- #menu_price.errors.full_messages.each do |message|
li = message
.form-group
= f.label :category
= f.select :category, options_for_select(#categories.map{ |c| [c.name] })
.form-group
= f.label :price
= f.number_field :price
.form-group
= f.label :description
= f.text_field :description
.form-group
= f.label :serves
= f.text_field :serves
= f.submit
= link_to 'Back', menu_prices_path, class:'button'
My models look like this
class Category < ActiveRecord::Base
has_many :menu_prices
validates :category, :presence => true
end
***********Updated***********
class CreateMenuPrices < ActiveRecord::Migration
def change
create_table :menu_prices do |t|
t.text :description, :null => false
t.decimal :price , :default => nil , :null => true
t.string :serves, :default => nil , :null => true
t.integer :small , :default => nil , :null => true
t.integer :regular, :default => nil , :null => true
t.integer :large, :default => nil , :null => true
t.integer :party, :default => nil, :null => true
t.timestamps null: false
end
add_reference :menu_prices, :categories
end
end
I understand that it wants a foreign key but I'm not sure how to go about submitting the foreign key in the form. Any help would be greatly appreciated.
******UPDATE******
My schema.rb is below
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "menu_prices", force: :cascade do |t|
t.text "description", null: false
t.decimal "price"
t.string "serves"
t.integer "small"
t.integer "regular"
t.integer "large"
t.integer "party"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "categories_id"
end
end
Since you're actually passing only category_id from view (and not whole Category object), instead of
f.label :category
and
f.select :category
you should have:
f.label :category_id
and
f.select :category_id
You should also make sure category_id column is present in menu_prices table.

Undefined local variable in Rails Controller

undefined local variable or method `dashboard_user' for #
Extracted source (around line #3):
class AdminController < ApplicationController
def user_creation
dashboard_user.create(:username => params[:username])
dashboard_user.create(:password => params[:password])
dashboard_user.create(:lastname => params[:lastname])
dashboard_user.create(:firstname => params[:firstname])
how do i fix this thanks i am new to ruby
After fixing this i am getting this
undefined method `attr_accessible' for
class DashboardUser < ActiveRecord::Base
self.table_name = "dashboard_user"
attr_accessible :username
attr_accessible :password
attr_accessible :lastname
attr_accessible :firstname
full controller
class AdminController < ApplicationController
def user_creation
DashboardUser.create(:username => params[:username])
DashboardUser.create(:password => params[:password])
DashboardUser.create(:lastname => params[:lastname])
DashboardUser.create(:firstname => params[:firstname])
DashboardUser.create(:middlename => params[:middlename])
DashboardUser.create(:phone => params[:phone])
redirect_to :action => 'user_creation'
end
private
def dashboard_params
params.require(:dashboard_user).permit(:id, :username, :password, :lastname, :firstname, :middlename , :phone)
end
end
create_table "dashboard_user", primary_key: "USER_ID", force: true do |t|
t.string "USER_NAME", limit: 50, null: false
t.string "NORMALIZED_USER_NAME", limit: 50
t.string "PASSWORD", limit: 50
t.string "LAST_NAME", limit: 50
t.string "FIRST_NAME", limit: 50
t.string "MIDDLE_NAME", limit: 50
t.string "PHONE", limit: 15
t.string "EMAIL_ID", limit: 100
t.integer "SEQ_QUES_ID"
t.string "SEQ_QUES_ANSWER", limit: 100
t.string "EXPIRE_PASSWORD_IND", limit: 1
t.date "EXPIRE_PASSWORD_DATE"
t.string "DEACTIVATED_IND", limit: 1
t.date "DEACTIVATED_DATE"
t.integer "ROLE_ID"
t.string "CREATED_BY", limit: 50
t.datetime "CREATED_DATE"
t.string "UPDATED_BY", limit: 50
t.datetime "UPDATED_DATE"
end
schema
On important rule in Rails is: Convention over Configuration
In convention your model file called dashboard_user but when you open that file, your model class name should be DashboardUser so following change to your code should solve the problem:
class AdminController < ApplicationController
def user_creation
DashboardUser.create(:username => params[:username])
DashboardUser.create(:password => params[:password])
DashboardUser.create(:lastname => params[:lastname])
DashboardUser.create(:firstname => params[:firstname])
end
end
In your controller you should be using the new permitted_params (As your using Rails 4)
It should look like this at the bottom of your controller
private
def dashboard_params
params.require(:dashboard_user).permit(:id, :user_name, :first_name, :last_name, :password)
end

why the belongs to association return a Fixnum object

rails 3.2.2
mysql2
I have the following relationships,
class TalkingCase < ActiveRecord::Base
belongs_to :medical_case
end
class MedicalCase < ActiveRecord::Base
has_many :talking_cases
end
in the console:
a=TalkingCase.first
a.medical_case
sometimes it return 0 and sometimes it work fine.
and I can use MedicalCase.find(xx) to get the medical_case object.
Do anyone meet this question?
The following is the console ouput:
Loading development environment (Rails 3.2.2)
[1] pry(main)> a=TalkingCase.first
TalkingCase Load (0.4ms) SELECT `talking_cases`.* FROM `talking_cases` LIMIT 1
=> #<TalkingCase id: 15, user_id: 231, talking_id: 7, nickname: "史丽", medical_case_id: 42, medical_case_name: "糖尿病肾病之一", created_at: "2012-06-21 03:38:36", updated_at: "2012-06-21 03:38:36">(this is ok)
[2] pry(main)> a.medical_case
MedicalCase Load (0.5ms) SELECT `medical_cases`.* FROM `medical_cases` WHERE `medical_cases`.`id` = 42 ORDER BY id desc LIMIT 1
=> 1
(this is stranger,I need the medical_case object)
tables in the schema is following:
create_table "talking_cases", :force => true do |t|
t.integer "user_id"
t.integer "talking_id"
t.string "nickname"
t.integer "medical_case_id"
t.string "medical_case_name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "medical_cases", :force => true do |t|
t.string "title", :null => false
t.string "bianhao", :null => false
t.integer "age"
t.string "gender", :limit => 1
t.integer "user_id", :null => false
t.integer "is_shared", :limit => 1
t.integer "is_elite", :limit => 1
t.integer "is_recommend", :limit => 1
t.string "share_reason"
t.string "other_cate_des"
t.string "keywords"
t.integer "comments_count", :default => 0
t.integer "click_count", :default => 0
t.integer "tap", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "fans_count"
end
Please specify the type of the association from the MedicalCase model too
class MedicalCase < ActiveRecord::Base
has_one :talking_case
end

Resources