I recently upgraded to rails 4.2 and I found that friendly ID stopped working. Not sure if this a bug or if I am literally just failing at using friendly id.
After the update my tests started failing, for example I have the following test:
context "Fiendly ID" do
it "should find by name" do
permission = FactoryGirl.create(:can_read)
Xaaron::Permission.find(permission.permission_name.parameterize).should_not eql nil
end
end
This test never use to fail but now its spitting out:
Failure/Error: Xaaron::Permission.find(permission.permission_name.parameterize).should_not eql nil
ActiveRecord::RecordNotFound:
Couldn't find Xaaron::Permission with 'id'=can_read2
# ./.bundle/gems/gems/activerecord-4.2.0/lib/active_record/core.rb:154:in `find'
# ./spec/models/xaaron/permission_spec.rb:21:in `block (3 levels) in <top (required)>'
With that in mind here is my model:
module Xaaron
class Permission < ActiveRecord::Base
extend FriendlyId
friendly_id :permission_name, use: [:slugged, :finders, :history]
has_many :roles_permissions
has_many :roles, :through => :roles_permissions
validates :permission_name, presence: true, uniqueness: true
def should_generate_new_friendly_id?
permission_name_changed?
end
end
end
notice the :finders. I am running 5.0.3 for Friendly ID. Is this something new with active record or have I failed at using Friendly ID?
The finders module is compatible with Rails 4.2. only in the 5.1. version (not yet released). You can of course already test the version but keep in mind that it's still in beta.
gem "friendly_id", "5.1.0.beta.1"
Related
I wanted to change from state_machine to state_machines. As I started to do this I encountered that the state was no longer changing from the initial state.
reviewed some stackoverflow and other guides: -
https://teamtreehouse.com/community/statemachines-usage
state-machines/state_machines-activerecord#33
Validation before persistance on state_machine gem
So changes i have made:
using state-machines-activerecord gem
add def initialize...
(see below)
I am now getting a rake setup error on my data. it
seems to have an issue with the validation the Contact ( a related
model that gets created first). Regardless of state, the Contact is
always created first. This ran fine before changing the gem.
any ideas? i think i have included all relevant code.
gem-file:
ruby "2.2.2"
gem "rails", "4.2.1"
gem "pg", "0.17.1" # postgresql database
gem "state_machines-activerecord"
gem-lock file
state_machines (0.4.0)
state_machines-activemodel (0.3.0)
activemodel (~> 4.1)
state_machines (>= 0.4.0)
state_machines-activerecord (0.3.0)
activerecord (~> 4.1)
state_machines-activemodel (>= 0.3.0)`
lead.rb (model) is:
`class Lead < ActiveRecord::Base
belongs_to :created_by_user, class_name: "User", inverse_of: :leads_created
belongs_to :contact
belongs_to :user
accepts_nested_attributes_for :contact
validates :contact, presence: true
state_machine :state, initial: :new_lead do
state :claimed
state :referred
state :broadcast
state :unclaimed`
`event :claim! do
transition all => :claimed
end
event :unclaim! do
transition claimed: :unclaimed
end
event :refer! do
transition new_lead: :referred
end
event :broadcast! do
transition all => :broadcast
end`
`def initialize(*)
super() # NOTE: This *must* be called, otherwise states won't get
initialized
end`
CONTROLLER
def lead_attributes
params.require(:lead).permit( :claimed,
:contact_id,
:status,
:state,
:user_id
setup_acceptance.rake
def create_contact(options={})
user = User.find_by(last_name: "Smith")
contact_attributes = { created_by_user: user, user: user }
attributes = contact_attributes.merge options
contact = Contact.create! attributes
contact.save!
contact
end
def create_lead(options={})
user = User.find_by(last_name: "Smith")
client_attributes = { user: user, created_by_user: user }
attributes = client_attributes.merge options
Lead.create! attributes ****(LINE 1311 where error message occurs)****
end
rake.setup
Lead.transaction do #(NOTE: THIS IS LINE 435)
create_lead( #(NOTE: THIS IS LINE 436)
user: User.find_by(last_name: "Smith"),
contact: Contact.find_by(last_name: "Lozar"),
status: 0,
state: "claimed"
}
]
)
error:
rake aborted!
ActiveRecord::RecordInvalid: Validation failed: Contact Please enter a value
/Users/workspace/ab/lib/tasks/setup_acceptance.rake:1311:in `create_lead'
/Users/workspace/ab/lib/tasks/setup.rake:436:in `block (2 levels) in <top (required)>
/Users/workspace/ab/lib/tasks/setup.rake:435:in `block in <top (required)>'
Tasks: TOP => setup_sample_data
(See full trace by running task with --trace)
with great thanks #avdi
The solution was to change:
super()
...which discards all the initialization arguments
to:
super
...which retains them implicitly.
The following spec passes fine in Ruby 2.1.5 but fails in 2.2.0 and I can't tell what that's all about:
# job.rb
class Job < ActiveRecord::Base
validates :link, :url => true
end
# job_spec.rb
require 'rails_helper'
describe Job do
describe "#create" do
["blah", "http://", " "].each do |bad_link|
it {
should_not allow_value(bad_link).for(:link)
}
end
end
end
fail log looks like this:
1) Job#create should not allow link to be set to "http://"
Failure/Error: should_not allow_value(bad_link).for(:link)
Expected errors when link is set to "http://",
got no errors
# ./spec/models/job_spec.rb:14:in `block (4 levels) in <top (required)>'
I find the only way to for that spec to pass with Ruby 2.2.0 is to include the validates_url gem in my project!!
Does anyone know this is about?
Maybe my solution isn't ideal, but it works.
Replace validates_url gem by validates gem. It has UrlValidator (written by me), which is well tested.
gem 'validates' # in Gemfile
validates :link, :url => true # you needn't to change something. Just remove validates_url from your Gemfile
P.S. It's a strange way - to test functionality of gem. Functionality should be tested in gem already.
P.P.S. I'm strongly recommend you to move to ruby 2.2.1 (or 2.2.2) instead of 2.2.0, because of 2.2.0 has a lot of bugs
I have a class called "Post" that should convert its markdown content to HTML when it is changed or it hasn't been converted yet. I'm trying to use the before_save callback with the if: argument, but I get this error on whatever I pass to the if when I try to run my tests:
Testing started at 1:55 ... rake aborted!
undefined method 'markdown_changed_or_html_nil?' for #<Post:0x000000053603d0>
C:/Users/user/Documents/GitHub/jw/app/models/post.rb:7:in <class:Post>
C:/Users/user/Documents/GitHub/jw/app/models/post.rb:1:in <top (required)>
C:/Users/user/Documents/GitHub/jw/test/test_helper.rb:12:in <class:TestCase>
C:/Users/user/Documents/GitHub/jw/test/test_helper.rb:5:in <top (required)>
C:/Users/user/Documents/GitHub/jw/test/models/post_test.rb:1:in <top (required)>
-e:1:in 'load'
-e:1:in '' Tasks: TOP => test:run => test:units (See full trace by running task with --trace) Run options: --seed 13458
# Running tests:
Finished tests in 0.002000s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Process finished with exit code 1
This is the model in question:
class Post < ActiveRecord::Base
include ActiveModel::Dirty
before_save :convert_markdown, if: :markdown_changed_or_html_nil?
belongs_to :user
validates :user, :title, :content_markdown, { presence: true, on: create }
validates_associated :user
protected
def convert_markdown
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, space_after_headers: true, underline: true)
self.content_html = markdown.render(content_markdown)
end
def markdown_changed_or_html_nil?
content_markdown.changed? || content_markdown.nil?
end
end
I'm using Ruby 2.0.0 and Rails 4.0.2.
I might well have made a really really basic mistake - I'm still learning Rails.
Edit: this is post_test.rb
require 'test_helper'
class PostTest < ActiveSupport::TestCase
test 'saving an empty object fails' do
new_post = Post.new
assert_not new_post.save
end
test 'validates that given user id corresponds to user' do
# This will create a user with a given id so we can use the next one up
test_user = User.create({ name: 'Johnny Test', email: 'johnny.test#example.com',
password: 'password', password_confirmation: 'password' })
# Use next id up - there's no reason it should be taken at this point
given_user_id = test_user.id + 1
post_with_invalid_user = Post.new({ title: 'Look at my glorious title', content_markdown: 'Sick content',
user_id: given_user_id })
assert_not post_with_invalid_user.save
end
test 'converts markdown into html' do
# This is a really really basic test just to make sure a conversion happens
new_post = Post.new({ title: 'Check out this markdown, baby', content_markdown: 'I got some *sick* markdown',
user_id: users(:paul).id })
assert_equal '<p>I got some <em>sick</em> markdown</p>', new_post.content_html
end
end
This may not be your primary issue (since your error message doesn't seem to relate to it), but you're not using changed? correctly. changed? needs to be called on your model object, optionally prefixed with your attribute name. So your condition method should look like:
def markdown_changed_or_html_nil?
# based on your method name, shouldn't this be:
# content_markdown_changed? || content_html.nil?
content_markdown_changed? || content_markdown.nil?
end
Find more information about Dirty methods at http://api.rubyonrails.org/classes/ActiveModel/Dirty.html.
ALSO
I'm pretty sure Rails 4 hasn't moved Dirty out of ActiveRecord::Base, so you don't need to manually include ActiveModel::Dirty in your model.
ALSO
This line:
validates :user, :title, :content_markdown, { presence: true, on: create }
Should be:
validates :user, :title, :content_markdown, { presence: true, on: :create }
validates :user, :title, :content_markdown, { presence: true, on: create }
should be
validates :user, :title, :content_markdown, presence: true, on: :create
I think ruby is just interpreting everything after validates :user, :title, :content_markdown as part of the validates function. Why this is, I have to little knowledge of the interpreter to know but ruby has alot of these 'weird' errors. Looking at the linenumbers as CaptChrisD said is always a good start when you encounter them.
My implementation was working with rails version 3.2. I am trying to upgrade my app to rails 4.1 but then I started getting error "uninitialized constant ActiveRecord::Transitions". According to transitions gem documentation on github (https://github.com/troessner/transitions) , it should work with rails >=4 without any issue.
code for active_record class with transitions is given below.
class Coupon < ActiveRecord::Base
has_paper_trail
include Rails.application.routes.url_helpers
include ActiveRecord::Transitions
state_machine do
state :available
state :issued
event :issue do
transitions :to => :issued, :from => :available
end
end
end
error I am getting is
`<class:Coupon>': uninitialized constant ActiveRecord::Transitions (NameError)
Although gem is included
gem "transitions", :require => ["transitions", "active_model/transitions"]
The docs say to include ActiveModel::Transitions. What you have done is include ActiveRecord::Transitions.
Typo maybe??
New to Ruby on Rails and having a problem when following Michael Hartl's tutorial.I'm using Rails 3.2.2 with Ruby 1.9.3. The issue looks very similar to another question that was raised but was unanswered:
Rails Error NoMethodError in UsersController#show error
I get the following error when attempting to add a new user via /signup
Gem::LoadError in UsersController#new
bcrypt-ruby is not part of the bundle. Add it to Gemfile.
Reloading the page gives the error:
NoMethodError in UsersController#new
undefined method `key?' for nil:NilClass
The problem seems to be related to the inclusion of the bcrypt-ruby gem, and the usage of the has_secure_password method in user.rb . Removing the call to has_secure_password in user.rb gets rid of the error and it goes to the signup page successfully.
user.rb:
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# password_digest :string(255)
#
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
validates :name, presence: true, length: { maximum: 50 }
valid_email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: valid_email_regex },
uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6}
end
users_controller.rb:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome!"
redirect_to #user
else
render 'new'
end
end
end
However, I cant find anything wrong with the inclusion of the bcrypt-ruby gem. In the Gemfile I have:
gem 'bcrypt-ruby', '3.0.1'
and the gem has also been generated in Gemfile.lock :
DEPENDENCIES
annotate (~> 2.4.1.beta)
bcrypt-ruby (= 3.0.1)
I've also added password_digest to the database via migration:
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
Any ideas ?
I'm going through the same tutorial and encountered the exact same problem.
My solution was to restart the web server. After installing the gem, I think the web server needs to be restarted so it is loaded.
Justin
Did you tried the 'bundle update' command, usually the bundler will take care of gems if you specified in the Gemfile. If you want to check the gem dependency please check http://rubygems.org/gems.
And if you are using windows(I know its strange- but some of our app works in windows only) there is some tricks to install bcrypt
Steps to install bcrypt.
1 Download Devkit and extract
you can download it from here http://rubyinstaller.org/downloads/
2 Place devkit it your jruby folder (in my case C:\applications\jruby\devkit)
3 You need to install ruby as well either 1.8.7 or 1.9(some times needs a system restart)
4 CD into devkit directory
5 Run ruby dk.rb init
6 Open config.yml and make sure that both your jruby installtion is listed. If not, ADD them. Save and close config.yml after you're done.
example:- C:/applications/jruby
7 Run ruby dk.rb install
8 jruby -S gem install bcrypt-ruby
Restarting the web server fixed it for me (had spork running in the background to speed up the running of the tests)