Insert record in assosiated model through console - ruby-on-rails

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
)

Related

Braintree rejects Discover cards on consecutive transactions

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
}
)

rolify multiple role checking should always include 1 more global role?

I check the docs but it only works when include 1 more global role.
how can I do multiple role checking without global role?
user.add_role :admin
user.add_role(:user, group)
user.add_role(:mentor, group)
user.has_all_roles? :admin, {:name => :mentor, :resource => group}
=> true
user.has_all_roles? {:name => :mentor, :resource => group}, {:name => :user, :resource => group}
=> SyntaxError: (irb):27: syntax error, unexpected =>, expecting '}'
user.has_any_role? :admin, {:name => :mentor, :resource => group}, {:name => :user, :resource => group}
=> true
user.has_any_role? {:name => :mentor, :resource => group}, {:name => :user, :resource => group}
=> SyntaxError: (irb):30: syntax error, unexpected =>, expecting '}'
Very annoying, but simply solved! Reason is that by writing
user.has_all_roles? {...}
you tell ruby: I'm giving a block to this method call... And that's obviously not what you want.
Simple fix: just add parentheses to your method call:
user.has_all_roles?( {...} )

Why the mass assignment code does not work

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

How do I update a child db table when populating database in ruby on ralls?

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.

Can I update all of my products to a specific user when seeding?

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 )

Resources