Background
We are executing the below method in order to charge a user and store his/her information in Braintree vault:
def store_in_vault
Braintree::Transaction.sale(:amount => amount,
:credit_card => {
:cardholder_name => cardholder_name,
:number => credit_card_number,
:expiration_date => "#{credit_card_expiration_month}/#{credit_card_expiration_year}",
:cvv => credit_card_cvv
},
:customer => {
:id => user.id,
:first_name => user.first_name,
:last_name => user.last_name,
:email => user.email,
:phone => user.phone_main
},
:billing => {
:first_name => user.first_name,
:last_name => user.last_name,
:street_address => street_address,
:extended_address => extended_address,
:locality => city,
:region => state,
:postal_code => zip,
:country_code_numeric => country
},
:options => {
:submit_for_settlement => false,
:store_in_vault_on_success => true
})
end
Later, we also put a hold on user's credit card as a security deposit.
All works well for most of the credit cards. However, when we try to put such security hold on Discover cards our transaction gets rejected with "Processor Declined" or "Declined" error. Note, that the initial transaction above to store user account in vault and charging credit card executes successfully. Just the later security hold transaction gets rejected.
Questions
Why this behavior happens only to Discover cards? How to fix it?
It is somehow related to Discover cards verification process. They require CVV and zip code to be included in transaction.
As per Braintree support :options in the above request have to include :add_billing_address_to_payment_method => true as follwoing:
:options => {
:submit_for_settlement => false,
:store_in_vault_on_success => true,
:add_billing_address_to_payment_method => true
}
In addition, during credit card replacement request (if required), one should add :billing_address information:
Braintree::CreditCard.create(
:customer_id => "#{user_id}",
:number => cc_number,
:expiration_date => "#{expiration_month}/#{expiration_year}",
:cardholder_name => cardholder_name,
:cvv => cvv,
:billing_address => {
:street_address => street_address,
:extended_address => extended_address,
:locality => city,
:region => state,
:postal_code => zip
},
:options => {
:make_default => true
}
)
Related
I have 2 tables User and Member and there relation is
In user
has_one :member, :class_name => 'User::Member'
Member
belongs_to :user
I am trying to insert data using console and I am using this code
u = User.create(
:group => UserGroup.find_by_slug(:members),
:first_name => 'abc',
:last_name => 'fgh',
:company_name => 'xyz',
:email => 'test#test.com',
:password => '123456',
:password_confirmation => '123456'
)
m = User::Member.create(
:user => u,
:pricing_plan => PricingPlan.order('RANDOM()').first,
:state => UserState.order('RANDOM()').first,
:industry => Industry.order('RANDOM()').first,
:fy_start_month => 7
)
It is throwing this error
syntax error, unexpected tIDENTIFIER, expecting $end
) m = User::Member.create(
I am wondering what is wrong with my syntax.Thanks in advance
This may be due to an invisible char (not whitespace). Your syntax seems to be ok, but if your editor allows you to show invisibles (in textmate, for example, go to view > show invisibles, try to do that. It sometimes happens to me that I insert invisibles instead of whitespace.
To give you an impression what I am talking about:
This is invisibles hidden
This is invisibles shown. The invisible lozenges you do not see in normal mode cause a syntax error:
I am assuming user_id is your foreign key which is associated with the users table.
If so use following
m= Member.create(
:user_id => u.id,
:pricing_plan => PricingPlan.order('RANDOM()').first,
:state => UserState.order('RANDOM()').first,
:industry => Industry.order('RANDOM()').first,
:fy_start_month => 7
)
try this
In your User Model
has_one :member
attr_accessible :member_attributes
accepts_nested_attributes_for :member
In your Member Model
belongs_to :user
then try in your console as well as your form
user = User.create(
:group => UserGroup.find_by_slug(:members),
:first_name => 'abc',
:last_name => 'fgh',
:company_name => 'xyz',
:email => 'test#test.com',
:password => '123456',
:password_confirmation => '123456'
)
and
user.build_member(
:pricing_plan => PricingPlan.order('RANDOM()').first,
:state => UserState.order('RANDOM()').first,
:industry => Industry.order('RANDOM()').first,
:fy_start_month => 7
)
or
member = Member.create(
:user_id => user.id,
:pricing_plan => PricingPlan.order('RANDOM()').first,
:state => UserState.order('RANDOM()').first,
:industry => Industry.order('RANDOM()').first,
:fy_start_month => 7
)
There is a mass assignment defined in sys_log model in our rails 3.1.4 app:
attr_accessible :log_date, :user_name, :user_id, :user_ip, :action_logged, :as => :new_log
A method is defined in application_controller to save the log:
def sys_logger(action_logged)
log = SysLog.new(:log_date => Time.now, :user_id => session[:user_id], :user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged, :as => :new_log)
log.save
end
However, the mass assignment does not work. Here is the warning message:
WARNING: Can't mass-assign protected attributes: log_date, user_id, user_name,
user_ip, action_logged, as
:new_log is not working as defined. What's wrong with the code above? Thanks so much.
The :as => :new_log is now part of the hash of attributes, instead of a separate option you pass in.
Adding some curly braces should help:
def sys_logger(action_logged)
log = SysLog.new({:log_date => Time.now, :user_id => session[:user_id],
:user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged }, :as => :new_log)
log.save
end
Or assigning it temporarily:
def sys_logger(action_logged)
attrs = { :log_date => Time.now, :user_id => session[:user_id],
:user_name => session[:user_name], :user_ip => session[:user_ip],
:action_logged => action_logged }
log = SysLog.new(attrs, :as => :new_log)
log.save
end
I have the following tables in my database:
User(s) - has one profile, has many PhotoAlbums
Profile(s) - belongs to user
PhotoAlbum(s) - belongs to user, has many photos
Photo(s) - belongs to PhotoAlbum
Faker works fine when it comes to populating my users table but I now wish to update my profiles table also but it doesn't work at all. The rows in the db still remain empty. I have no errors showing up when I run rake db:populate.
Am I missing something, please help me see where I'm going wrong and help me come up with a solution as this will help me when I need to populate my other tables too. What I learn from this answer can help me with other tasks I have coming up.
libs/task/sample_data.rake
namespace :db do
desc "Create user records in the development database."
task :populate => :environment do
require 'faker'
def randomDate(params={})
years_back = params[:year_range] || 5
latest_year = params [:year_latest] || 0
year = (rand * (years_back)).ceil + (Time.now.year - latest_year - years_back)
month = (rand * 12).ceil
day = (rand * 31).ceil
series = [date = Time.local(year, month, day)]
if params[:series]
params[:series].each do |some_time_after|
series << series.last + (rand * some_time_after).ceil
end
return series
end
date
end
def decimal_selection_array(start,limit,step_size=1)
decimal_array = (start..limit).step(step_size).map{|i| i.to_s}.to_a
decimal_array.insert(0,"Below #{start.to_f}")
decimal_array.insert(-1,"Above #{limit.to_f}")
end
100.times do |n|
username = "#{Faker::Name.first_name}#{n}"
u = User.create!(
:username => username,
:email => Faker::Internet.email,
:password => "foobar"
)
u.profile.update_attributes(
:motd => Faker::Lorem.words,
#Profile details
:first_name => Faker::Name.first_name,
:last_name => Faker::Name.last_name,
:birthday => randomDate(:year_range => 60, :year_latest => 22),
:gender => (1..2).to_a.sample,
:marital_status => (1..7).to_a.sample,
:sexual_preference => (1..3).to_a.sample,
:ethnicity => (1..10).to_a.sample,
:country => Faker::Address.country,
:location => Faker::Address.country,
#About the user
:about_me => Faker::Lorem.paragraph,
#Personal stats
:height => decimal_selection_array(5.0,7.0,0.1).to_a.sample,
:body_type => (1..7).to_a.sample,
:eye_colour => (1..6).to_a.sample,
:drugs => (1..4).to_a.sample,
:alcohol => (1..4).to_a.sample,
:cigarettes => (1..3).to_a.sample,
:likes => Faker::Lorem.sentence,
:dislikes => Faker::Lorem.sentence,
:bad_habits => Faker::Lorem.sentence,
#Favourite things
:food => Faker::Lorem.sentence,
:music => Faker::Lorem.sentence,
:television => Faker::Lorem.sentence,
:book => Faker::Lorem.sentence,
:animal => Faker::Lorem.sentence,
:place => Faker::Lorem.sentence,
:possesion => Faker::Lorem.sentence
)
end
end
end
Kind regards
User profile (u.profile) does not exist when calling u.profile.update_attributes(params).
You should call u.create_profile(params) instead.
Using nested attributes could also help.
I solved this issue by:
commenting out:
before_safe :build_profile
in my User model
and my editing my rake task to look like this:
# before running this task comment out: before_create :build_profile in user.rb in order to make this work correctly
namespace :db do
desc "Create user records in the development database."
task :populate => :environment do
require 'faker'
def randomDate
"#{(1900..2012).to_a.sample}-#{(1..12).to_a.sample}-#{(1..28).to_a.sample}"
end
def decimal_selection_array(start,limit,step_size=1)
decimal_array = (start..limit).step(step_size).map{|i| i.to_s}.to_a
decimal_array.insert(0,"Below #{start.to_f}")
decimal_array.insert(-1,"Above #{limit.to_f}")
end
1000.times do |n|
username = "#{Faker::Name.first_name}#{n+1}"
User.create!(
:username => username.gsub(/[^0-9a-z]/i, ''),
:email => Faker::Internet.email,
:password => "foobar"
)
Profile.create!(
:user_id => "#{n+1}",
:motd => Faker::Lorem.sentence,
#Profile details
:first_name => Faker::Name.first_name.gsub(/[^a-z]/i, ''),
:last_name => Faker::Name.last_name.gsub(/[^a-z]/i, ''),
:birthday => randomDate,
:gender => (1..2).to_a.sample,
:marital_status => (1..7).to_a.sample,
:sexual_preference => (1..3).to_a.sample,
:ethnicity => (1..10).to_a.sample,
:country => Faker::Address.country,
:location => Faker::Address.country,
#About the user
:about_me => Faker::Lorem.paragraph,
#Personal stats
:height => decimal_selection_array(5.0,7.0,0.1).to_a.sample,
:body_type => (1..7).to_a.sample,
:hair => (1..7).to_a.sample,
:eye_colour => (1..6).to_a.sample,
:drugs => (1..4).to_a.sample,
:alcohol => (1..4).to_a.sample,
:cigarettes => (1..3).to_a.sample,
:likes => Faker::Lorem.sentence,
:dislikes => Faker::Lorem.sentence,
:bad_habits => Faker::Lorem.sentence,
#Favourite things
:food => Faker::Lorem.sentence,
:sport => Faker::Lorem.sentence,
:music => Faker::Lorem.sentence,
:television => Faker::Lorem.sentence,
:book => Faker::Lorem.sentence,
:animal => Faker::Lorem.sentence,
:place => Faker::Lorem.sentence,
:possession => Faker::Lorem.sentence
)
end
end
end
I had to make a few adjustments to what Faker was passing into my db as things were failing validation. Things like usernames with characters other than letters and numbers and this also happened with last_name too. So I had to filter all that stuff out and then I ran the take task and successfully updated my database with 1000 users with profile information.
All I have to do is uncomment the before_create any time I want to add sample data to stop profile rows being created for users on create.
I also added user_id to attr_accessible in my Profile model so that the user_id column could be populated with numbers 1 to 1000 which would match them up with a user.
How can I update all of products to assign a certain user to them?
admin = User.create(:name => "Admin", :password => "password")
walmart = Store.create(:name => 'Walmart', :address => 'San Francisco, Palo Alto')
walmartprices = walmart.products.create
([
{:name => "Rice", :price => '5.93'},
{:name => "Chicken", :price => "2.24"},
{:name => "Milk", :price => '3.81'},
{:name => 'Eggs', :price => '2.78'}
])
walmartprices.update_attribute(:user => admin)
Of course this gives me an error:
undefined method `update_attribute' for #<Array:0x5342f70>
Is this possible? How can it be done?
EDIT
These are my associations:
Product
belongs_to :user and :store
Store
has_many :products
User
has_many :products
one naive way to do this is :
walmartprices.each{|record| record.update_attribute(user: admin) }
for better performance, use update_all :
Product.where( id: walmartprices.map(&:id) ).update_all( user: admin )
I can't get my any test to run because every user I try to fabricate generates validation errors.
I have the following test.
class BillTest < ActiveSupport::TestCase
def setup
load_all_sponsors
#the_bill = Bill.new(:govtrack_name => "h1")
#user1 = Fabricate(:user1)
#user2 = Fabricate(:user2)
My fabrications are defined by:
Fabricator(:user) do
email 'another_user_here#domain.com'
name 'anew user'
roles_mask 1
password "secret"
password_confirmation "secret"
polco_groups {[Fabricate(:polco_group, :name => 'foreign', :type => :custom)]}
end
Fabricator(:admin, :class_name => :user) do
email 'admin#yourdomain.com'
name 'Administrator'
roles_mask 5
password "secret"
password_confirmation "secret"
end
Fabricator(:registered, :class_name => :user) do
email 'registered_user#domain.com'
name 'Tim TheRegistered'
roles_mask 2
password "the_secret"
password_confirmation "the_secret"
polco_groups {[Fabricate(:polco_group, {:name => 'AL', :type => :state}),
Fabricate(:polco_group, {:name => 'AL01', :type => :district}),
Fabricate(:polco_group, {:name => "Kirk\'s Kids" , :type => :custom})]}
end
Fabricator(:user1, :class_name => :user) do
email 'user1#domain.com'
name 'User1'
roles_mask 2
password "the_big_secret"
password_confirmation "the_big_secret"
polco_groups {[Fabricate(:polco_group, {:name => 'AL', :type => :state}),
Fabricate(:polco_group, {:name => 'AL01', :type => :district}),
Fabricate(:polco_group, {:name => "Kirk\'s Kids" , :type => :custom})]}
end
Fabricator(:user2, :class_name => :user) do
email 'user2#domain.com'
name 'User2'
roles_mask 2
password "the_big_secret"
password_confirmation "the_big_secret"
polco_groups {[Fabricate(:polco_group, {:name => 'AL', :type => :state}),
Fabricate(:polco_group, {:name => 'FL01', :type => :district}),
Fabricate(:polco_group, {:name => "Ft. Sam Washington 1st Grade" , :type => :custom})]}
end
No matter which test runs, I get the same error
9) Error:
test_update_from_directory(BillTest):
Mongoid::Errors::Validations: Validation failed - Email is already taken, Email is already taken, Name is already taken.
test/unit/bill_test.rb:8:in `setup'
I have tried a number of different fabricators, inheriting in all kinds of different ways and nothing gets past this error. I'm pretty desperate for help on this one.
You should be user the "ffaker" gem to generate email addresses and the like in your specs. Also, you should be inheriting fields form previously defined fabricators, as illustrated below.
Fabricator(:user) do
email { Faker::Internet.email }
name { Faker::Name.name }
roles_mask 1
password "secret"
password_confirmation "secret"
polco_groups {[Fabricate(:polco_group, :name => 'foreign', :type => :custom)]}
end
Fabricator(:admin, :from => :user) do
roles_mask 5
end
Fabricator(:registered, :from => :user) do
roles_mask 2
polco_groups {[Fabricate(:polco_group, :name => 'AL', :type => :state),
Fabricate(:polco_group, :name => 'AL01', :type => :district),
Fabricate(:polco_group, :name => "Kirk\'s Kids" , :type => :custom)]}
end
Fabricator(:user1, :from => :registered)
Fabricator(:user2, :from => :registered) do
polco_groups {[Fabricate(:polco_group, {:name => 'AL', :type => :state}),
Fabricate(:polco_group, {:name => 'FL01', :type => :district}),
Fabricate(:polco_group, {:name => "Ft. Sam Washington 1st Grade" , :type => :custom})]}
end
It is unrelated to your issue, but it looks like user1 and user2 should just be calls to Fabricate and not actually defined as Fabricators. I don't recommend putting that much explicit information in the Fabricator. You should only be defining was is necessary to generate a valid object. Any specific data should be in the service of a particular spec.
After running in to Machinist and Fabricator issues with Mongoid I've settled on FactoryGirl - the syntax feels like a step back - but it works.
The issues I had with the others were related to validation, STI and polymorphism.