Rails regex validations throw no method error in Heroku - ruby-on-rails

I have used the following regex to validate the nic number in my rails app :
VALID_NIC_REGEX = /\A\d{9}[V|v|x|X]\z/i
validates :nic, presence: true, allow_blank: true, format: { with: VALID_NIC_REGEX }, uniqueness: { case_sensitive: false }
When I test it in my local machine, everything works fine. But after uploading to heroku, it give an error while trying to save the member with a value in the nic field. Both valid and invalid values give the error. If there's no value in the nic field, it saves the member. In the heroku log, I found this error :
NoMethodError (undefined method `limit' for nil:NilClass):
app/controllers/members_controller.rb:117:in `update'
So, I commented out the two validation lines and uploaded the site to Heroku. Now it works. Can some one please explain this? Thank you.
Controller update action :
def update
#source = params[:source]
#telfie = params[:telfie].to_i
#member = Member.find(params[:id])
#tel = Array.new
(1..#telfie.to_i).each do |i|
#tel << params[:tele][:"#{'tele'}#{i}"]
end
#params[:tele] = #tel
if params[:commit] == 'More Numbers'
#telfie = #telfie + 1
render 'edit'
else
if params[:commit] == 'Less Numbers'
if #telfie > 1
#telfie = #telfie - 1
render 'edit'
else
flash.now[:error] = "Can't remove all contact fields!"
render 'edit'
end
else
if #member.update_attributes(member_params)
#member.tele = #tel
#member.save
flash[:success] = "Member #{#member.name} Successfully Updated!"
if params[:commit] == 'Save Member and Add Associates'
redirect_to new_associate_url(memberid: #member.id, source: "memberv" )
else
if #source == "database"
redirect_to database_path
else
redirect_to member_url(#member)
end
end
else
render 'edit'
end
end
end
end

Related

How to test destroy failure in ruby-on-rails

everyone.
I'm gonna test an active record object destroy failure but I've problems creating a failure situation.
I have a before_filter method called 'require_user_payment_info' which validates the #payment_info object before the delete method is called, so I can't create a 'bad' #payment_info object before the delete method is called.
Here's the require_user_payment_info method:
def require_user_payment_info
#payment_info = credit_card_model.slave.find_by_user_guid(user_guid)
if !#payment_info || #payment_info.user_guid != user_guid
redirect_to(:controller => 'store', :action => 'index') and return false
else
if((#payment_info.card_expires_year.to_i < Date.today.year) ||
((#payment_info.card_expires_month.to_i < Date.today.month) && (#payment_info.card_expires_year.to_i == Date.today.year)))
#payment_info.card_account_public = "" #clear this out so the user is forced to re-enter the credit card number
#payment_info.valid?
flash.now[:error] = t('ui_flash_errors.card_expired_error')
end
end
end
And the actual delete method:
def delete
# required to be called via a delete request
redirect_to :action => 'edit' and return if !request.delete?
if #payment_info.destroy
flash[:notice] = "Delete SUCCESSFUL"
redirect_to :action => 'new'
else
flash[:error] = "Delete failed"
redirect_to :action => 'edit'
end
Any ideas?
This is my solution:
def test_delete
payment_info = Factory.create(:payment_info, :user_guid=>#user.guid, :card_expires_month=>'04',
:card_expires_year=>(Date.today.year+2).to_s, :cardholder_city=>"test city",
:cardholder_state=>'NC', :cardholder_country=>'US', :cardholder_zip=>'27612')
PaymentInfo.any_instance.stubs(:destroy).returns(false)
delete(:delete, {}, #session)
assert_response(:redirect)
assert_equal false, assigns(:payment_info).blank?
assert_redirected_to({:controller=>'account', :action=>'edit'})
assert_equal flash[:error], "There was an error deleting your credit card information. Please try again."
end

How to use reload without validations?

I'm setting up basic tests for a rails app, I'm wondering how the reload function works. Rails generated the basic crud tests, I adapted them to my need, but it seems like the reload function doesn't work.
I create a user with valid params, then ask to change its name, but it seems like nothing's updated (output is still name: 'Toto' instead of name: 'Tata').
Here's the code sample, I just followed the basic rspec tutorial, still, nothing gets updated. Any idea why ?
context "with valid params" do
let(:new_attributes) { {name: 'Tata'} }
it "updates the requested creator" do
creator = Creator.create! valid_attributes
puts creator.id
puts new_attributes
put :update, :id => creator.id, :creator => new_attributes
creator.reload
puts creator.name.to_yaml
expect(creator.attributes).to include( { "name" => 'Tata' } )
...
Here's the matching controller method
def update
#creator = Creator.find(params[:id])
authorize #creator
#creator.completed = true
params[:hidden] == 'false' ? #creator.hidden = false : #creator.hidden = true
#creator.update(creator_params)
if params[:user].present?
if params[:user][:picture].present?
#creator.picture = params[:user][:picture]
end
end
if #creator.save
if iban.nil? || (iban && !iban.valid?)
flash[:alert] = "Veuillez entrer un IBAN valide"
redirect_to edit_creator_path(#creator)
elsif params[:brief_id].present?
flash[:notice] = "Informations mises à jour"
redirect_to brief_path(params[:brief_id])
else
flash[:notice] = "Informations mises à jour"
redirect_to creator_path(#creator)
end
else
puts #creator.errors.full_messages
render :edit
end
end

Set value to belongs_to attributes in rails create action

I'm trying to set the title of a Page in my create action.
I would need to page.translation.title = params[:page][:title]
def create
#page = Page.new(params[:page])
#page.translation.title = params[:page][:title]
if #page.save
redirect_to admin_pages_path
else
render :new
end
end
Also tried
#translation = #page.translation.build(title: params[:page][:title])
from the console when I run:
p = Page.last
p.translation.title
=> nil -----> right now after its created, title is nil.
p.translation.title = "foo"
=> "foo"
This is what I what in my create action. any help would be greatly
appreciated. Thank you.
Update:
I'm using this on a legacy application that's running on refinerycms 2.1.0.dev
Relevant code:
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page_part.rb#L10
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page.rb#L45-L49
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page.rb#L11-L14
Solution
def create
#page = Refinery::Page.new(params[:page])
if #page.save!
#page.translations.create(slug: #page.slug,
title: params[:page][:title],
locale: params[:switch_locale])
flash.notice = t(
'refinery.crudify.created',
what: "'#{#page.title}'"
)
redirect_to admin_pages_path
else
render :new
end
end

ROR strip issues

i am using strip for check email but it gave me this issues please help me out .
NoMethodError in UsersController#check_email
undefined method `strip' for nil:NilClass
def check_email
if params[:email].blank?
#email = params[:email].strip
user = User.find_by_email(#email)
if user.nil?
text = "false"
else
text = "true"
end
render :text => text
else
render :text =>text
end
end
Based on the feedback by Sergio and Brad:
def check_email
text = params[:email].present? && User.where(email: params[:email].strip).exists?
render :text => text
end
Update it as:--
def check_email
if params[:email].present?
#email = params[:email].strip
user = User.find_by_email(#email)
unless user.present?
text = "false"
else
text = "true"
end
render :text => text
else
render :text =>text
end
end
if params[:email].blank? should be if params[:email].present?.
Problem is when params[:email] is nil you are calling strip method on it i.e. nil.strip
So change it to followin
def check_email
if params[:email].present?
#email = params[:email].strip
user = User.find_by_email(#email)
text = user.nil? ? "false" : "true"
else
text = "please enter email address"
end
render :text =>text
end
You have small error, you need use:
unless params[:email].blank?
Or,
if params[:email].present?
I recommend to read about blank? vs nil? vs empty? vs present?

Why is my rspec test failing with ActionController::RoutingError:?

Basically I'm stumped as to why this particular test is failing. The page works fine when I go in and test it out by hand but the test keeps failing. First off, here's the error.
2) Setlist Pages Edit page adding a song
Failure/Error: click_button submit
ActionController::RoutingError:
No route matches {:action=>"edit", :controller=>"setlists", :id=>nil}
# ./app/controllers/allocations_controller.rb:15:in `create'
# (eval):2:in `click_button'
# ./spec/requests/setlist_pages_spec.rb:79:in `block (4 levels) in <top (required)>'
I realise that the id is set to nil but I know that when the test initially visits the page it renders because tests for content pass. I'm not sure why it points to the create controller when I'm testing the edit action as well? The test is shown below:
before do
#setlist = Setlist.create(date: Date.today, morning: true)
end
...
describe "Edit page" do
let(:admin) { FactoryGirl.create(:admin) }
let(:submit){ "Add Song" }
before do
#secondSong = FactoryGirl.create(:song)
sign_in admin
visit edit_setlist_path(#setlist)
end
it{ should have_content("Edit a Setlist")}
describe "adding a song" do
before do
select("#{#secondSong.title} by #{#secondSong.artist}", from: 'Songs')
click_button submit
end
it{ should have_selector('div.alert.alert-success')}
it "should create a new allocation" do
expect{click_button submit}.to change(Allocation, :count).by(1)
end
end # end adding a song
end # end edit test
Controller code as requested:
def create
#setlist = Setlist.new(params[:setlist])
if #setlist.save
#success!
flash[:success] = "Setlist saved"
##setlist.allocations.build produce invalid allocation with nil id
redirect_to setlist_path(#setlist)
else
#FAIL!
render 'new'
end
end
def edit
#songs= Song.search(params[:search])
##songs = Song.all(order: 'title')
#setlist = Setlist.find(params[:id])
#allocations = #setlist.allocations
#allocation = Allocation.new
#selections = Song.all.collect {|s| [ [s.title, s.artist].join(" by "), s.id ]}
end
def update
#setlist = Setlist.find(params[:id])
#selections = Song.all.collect {|s| [ [s.title, s.artist].join(" by "), s.id] }
#allocations = #setlist.allocations
#allocation = Allocation.new
#Allocation parameters
#allocation.song_id = params[:allocation][:song_id]
#allocation.setlist_id = #setlist.id
#allocation.songPosition = #setlist.songs.count + 1
if #setlist.update_attributes(params[:setlist])
if #allocation.save
flash[:success] = "SETLIST SAVED!"
redirect_to edit_setlist_path(#setlist)
else
flash[:fail] = "Sorry there was an error adding songs to the setlist"
render 'edit'
end
else
flash[:fail] = "Invalid Set"
render 'edit'
end
end
Any pointers would be much appreciated!

Resources