has_one, dependent: destroy not working - ruby-on-rails

I am using Devise for my user authentication and would like to destroy an associated profile along with the user.
My failing spec looks like this:
it "should destroy associated profile" do
profile = #user.profile
#user.destroy
expect(profile).to be_nil
end
And
In my user model:
has_one :profile, dependent: :destroy
In my profile model:
belongs_to :user
In the console, I can reproduce the issue like this:
2.0.0p247 :001 > #user = FactoryGirl.create(:user)
(1.5ms) BEGIN
User Exists (2.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'person946979#example.com' LIMIT 1
User Exists (1.7ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('person946979#example.com') LIMIT 1
SQL (15.7ms) INSERT INTO "users" ("created_at", "email", "encrypted_password", "name", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Fri, 16 Aug 2013 01:21:12 UTC +00:00], ["email", "person946979#example.com"], ["encrypted_password", "$2a$10$0704XOlw.6ZE4HEfDhaIeuwnEbbJZvZda3Jwr052aLS5z3G77Dgja"], ["name", "Example User"], ["updated_at", Fri, 16 Aug 2013 01:21:12 UTC +00:00]]
SQL (3.8ms) INSERT INTO "profiles" ("created_at", "updated_at", "user_id") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Fri, 16 Aug 2013 01:21:12 UTC +00:00], ["updated_at", Fri, 16 Aug 2013 01:21:12 UTC +00:00], ["user_id", 25]]
Profile Load (3.4ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["user_id", 25]]
(2.2ms) COMMIT
=> #<User id: 25, email: "person946979#example.com", encrypted_password: "$2a$10$0704XOlw.6ZE4HEfDhaIeuwnEbbJZvZda3Jwr052aLS5...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2013-08-16 01:21:12", updated_at: "2013-08-16 01:21:12", name: "Example User">
2.0.0p247 :002 > #user.destroy
(1.0ms) BEGIN
SQL (2.5ms) DELETE FROM "profiles" WHERE "profiles"."id" = $1 [["id", 4]]
SQL (5.4ms) DELETE FROM "users" WHERE "users"."id" = $1 [["id", 25]]
(2.0ms) COMMIT
=> #<User id: 25, email: "person946979#example.com", encrypted_password: "$2a$10$0704XOlw.6ZE4HEfDhaIeuwnEbbJZvZda3Jwr052aLS5...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2013-08-16 01:21:12", updated_at: "2013-08-16 01:21:12", name: "Example User">
Interestingly, the user appears to actually have been deleted.
2.0.0p247 :003 > #user.reload.destroy
User Load (2.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 25]]
ActiveRecord::RecordNotFound: Couldn't find User with id=25
What is going on here?

Your model seems fine. Try something like this:
it "should destroy associated profile" do
profile = #user.profile
#user.destroy
expect(Profile.find(profile.id)).to be_nil
end
Like Heungju said, while the database row that corresponds to profile is being destroyed, the variable itself isn't.

How about this?
it "should destroy associated profile" do
profile = #user.profile
#user.destroy
expect(#user.profile).to be_nil
end
After #user.destroy, the 'profile', variable that expected to be nil, was not changed. I think...

Rewriting my spec like this does what I need:
it "should destroy associated profile" do
expect {
#user.destroy
}.to change(Profile, :count).by(-1)
end

Related

rails_admin won't let me keep my enum field as nil

Model:
class Reservation < ApplicationRecord
# https://naturaily.com/blog/ruby-on-rails-enum
enum recurrence: {
daily: 0,
weekly: 1,
monthly: 2,
annually: 3
}, _prefix: :recurring
belongs_to :user
validates :name, :user_id, presence: true
...
end
Migration:
class CreateReservations < ActiveRecord::Migration[5.2]
def change
create_table :reservations do |t|
t.string 'name', null: false
...
t.boolean 'recurring', default: false, null: false
t.integer 'recurrence', index: true, allow_blank: true, default: nil # trying a lot of things here
t.datetime 'expire_time'
...
end
end
end
Works as expected in the console:
2.4.5 :002 > res = Reservation.new(name: 'test', user_id: 1)
=> #<Reservation id: nil, name: "test", recurring: false, recurrence: nil, date: nil, start_time: nil, end_time: nil, expire_time: nil, user_id: 1, created_at: nil, updated_at: nil>
2.4.5 :003 > res.valid?
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
=> true
2.4.5 :004 > res.save
(0.2ms) BEGIN
Reservation Create (0.5ms) INSERT INTO "reservations" ("name", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "test"], ["user_id", 1], ["created_at", "2019-09-24 20:42:40.933959"], ["updated_at", "2019-09-24 20:42:40.933959"]]
(2.1ms) COMMIT
=> true
2.4.5 :005 > res.reload
Reservation Load (0.3ms) SELECT "reservations".* FROM "reservations" WHERE "reservations"."id" = $1 LIMIT $2 [["id", 5], ["LIMIT", 1]]
=> #<Reservation id: 5, name: "test", recurring: false, recurrence: nil, date: nil, start_time: nil, end_time: nil, expire_time: nil, user_id: 1, created_at: "2019-09-24 20:42:40", updated_at: "2019-09-24 20:42:40">
2.4.5 :006 > res.recurrence
=> nil
And yet, in Rails Admin, when I create or edit a record, they all get assigned to the first enum. Even when I intentionally delete the value from the form, it still saves the record with the first enum value.
Rails Admin:
config.model Reservation do
weight 2
parent Event
list do
field :name
field :display_date do
formatted_value { bindings[:object].display_date }
end
field :recurrence, :active_record_enum # should be unnecessary, but trying everything
field :expire_time
field :user do
label 'Creator'
formatted_value { bindings[:object].user.name }
end
end
end
I have tried:
not indexing this field (thinking Rails Admin wants a value for indexed columns)
ensuring `:active_record_enum` is declared on `field :recurrence`
As suggested, here's the related section of the log:
Started POST "/admin/reservation/new" for ::1 at 2019-09-25 10:09:50 -0400
Processing by RailsAdmin::MainController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"VbhHM7YD+oQvwMYIQzMHyT5e0MXFFuN3pyH/1s6yM8n6kqKvywZ5E8zaABMKhOU+oWpfU1Kk55FWYjL9TzbkbQ==", "reservation"=>{"name"=>"logs", "date"=>"", "start_time"=>"", "end_time"=>"", "recurring"=>"0", "recurrence"=>"", "expire_time"=>"", "start_time_of_day"=>"", "end_time_of_day"=>"", "day_of_week"=>"", "date_of_month"=>"", "date_of_year"=>"", "user_id"=>"1"}, "return_to"=>"http://localhost:3000/admin/reservation", "_save"=>"", "model_name"=>"reservation"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) BEGIN
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Reservation Create (0.4ms) INSERT INTO "reservations" ("name", "recurrence", "day_of_week", "date_of_month", "date_of_year", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["name", "logs"], ["recurrence", 0], ["day_of_week", ""], ["date_of_month", ""], ["date_of_year", ""], ["user_id", 1], ["created_at", "2019-09-25 14:09:50.926864"], ["updated_at", "2019-09-25 14:09:50.926864"]]
(1.3ms) COMMIT
Redirected to http://localhost:3000/admin/reservation
Completed 302 Found in 26ms (ActiveRecord: 3.0ms)
And, sure enough the param "recurrence"=>"" is transformed into ["recurrence", 0]
It seems to be a known issue, but if it's a legit bug, I still need help with a work-around. Anyone solved this already?
This technically works, but I'm thinking it's not the ideal solution:
If you declare your enum as a hash (not an array) and don't assign anything to 0, it works.
In my case enum recurrence: { daily: 0, weekly: 1, monthly: 2, annually: 3 } becomes enum recurrence: { daily: 1, weekly: 2, monthly: 3, annually: 4 }
The logs show the param isn't passed to the SQL:
Started POST "/admin/reservation/new" for ::1 at 2019-09-25 10:21:17 -0400
Processing by RailsAdmin::MainController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Joyg5VuquwMMKg+ps2zg9t+8r0DZ0iOIkqRlk1cBkemJpkV5Jq84lO8wybL62wIBQIgg1k5gJ25j56i41oVGTQ==", "reservation"=>{"name"=>"test3", "date"=>"", "start_time"=>"", "end_time"=>"", "recurring"=>"0", "recurrence"=>"", "expire_time"=>"", "start_time_of_day"=>"", "end_time_of_day"=>"", "day_of_week"=>"", "date_of_month"=>"", "date_of_year"=>"", "user_id"=>"1"}, "return_to"=>"http://localhost:3000/admin/reservation", "_save"=>"", "model_name"=>"reservation"}
User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) BEGIN
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Reservation Create (1.3ms) INSERT INTO "reservations" ("name", "day_of_week", "date_of_month", "date_of_year", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["name", "test3"], ["day_of_week", ""], ["date_of_month", ""], ["date_of_year", ""], ["user_id", 1], ["created_at", "2019-09-25 14:21:17.091292"], ["updated_at", "2019-09-25 14:21:17.091292"]]
(5.7ms) COMMIT
The param contains "recurrence"=>"", but the INSERT INTO doesn't have an array for recurrence like it did before.
And I confirmed in the console:
2.4.5 :001 > res = Reservation.first
Reservation Load (0.4ms) SELECT "reservations".* FROM "reservations" ORDER BY "reservations"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Reservation id: 4, name: "test3", date: nil, start_time: nil, end_time: nil, recurring: false, recurrence: nil, expire_time: nil, start_time_of_day: nil, end_time_of_day: nil, day_of_week: "", date_of_month: "", date_of_year: "", user_id: 1, created_at: "2019-09-25 14:21:17", updated_at: "2019-09-25 14:21:17">
2.4.5 :002 > res.recurrence
=> nil
However, it seems to me like I'm just passing a dis-allowed value and letting Rails reject it. This still seems to be an issue with Rails Admin, specifically with integer enums.
It could be a restriction of using hashes, because nil values should work. Since you're mapping those to 0-indexed values, you should just use a symbol array. The ActiveRecord::Enum documentation (linked above) states:
Note that when an array is used, the implicit mapping from the values to database integers is derived from the order the values appear in the array. In the example, :active is mapped to 0 as it's the first element, and :archived is mapped to 1. In general, the i-th element is mapped to i-1 in the database.
So you should be able to just use an array of symbols for this.

activerecord model with 2 parent levels

A user can have many questions. Many users can participate on a question and provide multiple answers to the same question. Relation between users and questions seems to be working fine. Problem is with answers.
model/user.rb
has_and_belongs_to_many :questions
has_many :answers
model/question.rb
has_and_belongs_to_many :users
has_many :answers
model/answer.rb
has_one :question
has_one :user, :through => :question
Here is what I'm trying in the console:
irb(main):022:0> u1.questions.first.answers.create(answer: "foo1", order:1)
(0.2ms) BEGIN
Answer Exists (0.5ms) SELECT 1 AS one FROM "answers" WHERE "answers"."answer" = $1 LIMIT $2 [["answer", "foo1"], ["LIMIT", 1]]
SQL (0.4ms) INSERT INTO "answers" ("created_at", "updated_at", "answer", "order", "question_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", 2017-03-31 19:31:04 UTC], ["updated_at", 2017-03-31 19:31:04 UTC], ["answer", "foo1"], ["order", 1], ["question_id", 1]]
(13.5ms) COMMIT
=> #<Answer id: 6, created_at: "2017-03-31 19:31:04", updated_at: "2017-03-31 19:31:04", answer: "foo1", order: 1, user_id: nil, question_id: 1>
irb(main):023:0> u1.questions.first.answers.create(answer: "bar1", order:2)
(0.4ms) BEGIN
Answer Exists (0.9ms) SELECT 1 AS one FROM "answers" WHERE "answers"."answer" = $1 LIMIT $2 [["answer", "bar1"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "answers" ("created_at", "updated_at", "answer", "order", "question_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", 2017-03-31 19:31:04 UTC], ["updated_at", 2017-03-31 19:31:04 UTC], ["answer", "bar1"], ["order", 2], ["question_id", 1]]
(19.9ms) COMMIT
=> #<Answer id: 7, created_at: "2017-03-31 19:31:04", updated_at: "2017-03-31 19:31:04", answer: "bar1", order: 2, user_id: nil, question_id: 1>
irb(main):024:0> u2.questions.first.answers.create(answer: "foo2", order:1)
(0.7ms) BEGIN
Answer Exists (0.6ms) SELECT 1 AS one FROM "answers" WHERE "answers"."answer" = $1 LIMIT $2 [["answer", "foo2"], ["LIMIT", 1]]
SQL (0.9ms) INSERT INTO "answers" ("created_at", "updated_at", "answer", "order", "question_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", 2017-03-31 19:31:04 UTC], ["updated_at", 2017-03-31 19:31:04 UTC], ["answer", "foo2"], ["order", 1], ["question_id", 1]]
(16.7ms) COMMIT
=> #<Answer id: 8, created_at: "2017-03-31 19:31:04", updated_at: "2017-03-31 19:31:04", answer: "foo2", order: 1, user_id: nil, question_id: 1>
irb(main):025:0> u2.questions.first.answers.create(answer: "bar2", order:2)
(0.5ms) BEGIN
Answer Exists (0.6ms) SELECT 1 AS one FROM "answers" WHERE "answers"."answer" = $1 LIMIT $2 [["answer", "bar2"], ["LIMIT", 1]]
SQL (0.5ms) INSERT INTO "answers" ("created_at", "updated_at", "answer", "order", "question_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", 2017-03-31 19:31:05 UTC], ["updated_at", 2017-03-31 19:31:05 UTC], ["answer", "bar2"], ["order", 2], ["question_id", 1]]
(14.9ms) COMMIT
=> #<Answer id: 9, created_at: "2017-03-31 19:31:05", updated_at: "2017-03-31 19:31:05", answer: "bar2", order: 2, user_id: nil, question_id: 1>
It's obvious something is wrong given the fact user_id is null, unless I specify. I expect user_id populated given the fact I'm creating it from a user object through a question.
irb(main):027:0* u1.questions.first.answers.count
(0.7ms) SELECT COUNT(*) FROM "answers" WHERE "answers"."question_id" = $1 [["question_id", 1]]
=> 4
As I can see here, it just filters by question_id. I expect to retrieve the answers from question_id AND user_id
Can this problem be fixed? Should I just do it in another way?
Thanks
UPDATE
As a summary, this is what I would like to achieve:
User.first.answers.where(question_id: 1)
Where the query looks like:
SELECT "answers".* FROM "answers" WHERE "answers"."user_id" = $1 AND "answers"."question_id" = $2 [["user_id", 1], ["question_id", 1]]
I would like to be able to do:
User.first.questions.first.answers
And get the answers for user_id and question_id
Thanks
I think you should use belongs_to for :user and :question (instead of has_one) and set user manually to your answers from current_user in controller.

Can't get Braintree Error Messages to show in Rails 4

On my site, a user registers and gives their credit card information in the same form. The form uses Devise to save the user. I needed to import the actual devise code into the controller (a bad practice, i know, but with Braintree I couldn't see any other way to wrap the user and charge into one transaction). I finally got the whole thing to work except I am having trouble with Braintree error messages. I just tried creating a transaction with an amount of $2600 which should trigger a Braintree error and display a message, but no such error was triggered. Here is my code:
def create
nonce_from_the_client = params[:payment_method_nonce]
# code taken from devise
build_resource(sign_up_params)
begin
#charge = resource.charges.build
#charge.nonce = nonce_from_the_client
braintree_call = nil
#braintree_errors = nil
ActiveRecord::Base.transaction do
puts "beforer resource saved".green
resource.save!
puts "resource saved".green
puts "charge built".green
puts "before call_braintree".green
braintree_call = #charge.call_braintree!
if braintree_call.success? && !braintree_call.errors.any?
puts "braintree_call was a success".green
#charge.save
#do nothing. All good
else
puts "braintree error".red
#braintree_errors = braintree_call.errors
braintree_call.errors.each do |error|
puts "#{error.code}\n".red
puts "#{error.message}".red
end
raise "#Charge Failed"
end
end
rescue
puts "#charge #{#charge.inspect}".red
puts "#charge errors: #{#charge.errors.inspect}".red
end
yield resource if block_given?
if resource.persisted?
puts "resource persisted".green
if resource.active_for_authentication?
flash[:success] = "Welcome! You have signed up successfully."
# set_flash_message! :notice, :signed_up
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
puts "not sure about this".blue
# set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}"
flash[:danger] = "signed_up_but_#{resource.inactive_message}"
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
puts "resource did not persist".red
clean_up_passwords resource
set_minimum_password_length
# respond_with resource
puts "NOW WE KNOW".on_red
render 'new' #not sure if this works
end
puts "resource errors are #{resource.errors.inspect}".red
end
And here is the model for Charge that includes the call_braintree method above:
class Charge < ActiveRecord::Base
belongs_to :user
attr_accessor :nonce
after_create :activate_user_account
def activate_user_account
puts "in the activate user account after_Create method".green
self.user.activate
end
def set_amount
amount = self.user.plan.amount * self.user.plan.length
puts "amount is #{amount} and is class #{amount.class}".green
return amount
end
def call_braintree!
puts "in call braintree".green
result = Braintree::Transaction.sale(
:amount => "#{self.set_amount}",
:payment_method_nonce => self.nonce,
:options => {
:submit_for_settlement => true
}
)
end
end
Here are the server logs this generates:
Started POST "/users" for 127.0.0.1 at 2016-02-26 15:06:29 -0500
Processing by Users::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Z0jHeFqXJk6iEwdEohilVd2Io85NKoPuzUepjfSXxU0=", "user"=>{"type"=>"Presenter", "plan_id"=>"2", "organization_name"=>"", "first_name"=>"David", "last_name"=>"Applebau,", "email"=>"asfdjhfasdlk#dffadsdf.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "telephone"=>"6462343800", "group_code"=>""}, "field-fnames"=>"", "field-lnames"=>"", "payment_method_nonce"=>"815abd1c-0be5-40e4-8135-a468021c8b75"}
(0.2ms) BEGIN
beforer resource saved
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'asfdjhfasdlk#dffadsdf.com' LIMIT 1
Plan Load (0.1ms) SELECT "plans".* FROM "plans" WHERE "plans"."id" = $1 LIMIT 1 [["id", 2]]
SQL (0.2ms) INSERT INTO "users" ("created_at", "email", "encrypted_password", "first_name", "last_name", "organization_name", "plan_id", "plan_length", "plan_start_date", "plan_status", "telephone", "type", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING "id" [["created_at", "2016-02-26 20:06:29.294712"], ["email", "asfdjhfasdlk#dffadsdf.com"], ["encrypted_password", "$2a$10$jeIa3c.i73f/hBV7ne/Dfu0MAawQzoNak808zLqjjkFeJKmXt78yK"], ["first_name", "David"], ["last_name", "Applebau,"], ["organization_name", ""], ["plan_id", 2], ["plan_length", 1], ["plan_start_date", "2016-02-26 20:06:29.289691"], ["plan_status", "active"], ["telephone", "6462343800"], ["type", "Presenter"], ["updated_at", "2016-02-26 20:06:29.294712"]]
SQL (0.1ms) INSERT INTO "charges" ("created_at", "updated_at", "user_id") VALUES ($1, $2, $3) RETURNING "id" [["created_at", "2016-02-26 20:06:29.307071"], ["updated_at", "2016-02-26 20:06:29.307071"], ["user_id", 20]]
in the activate user account after_Create method
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 20]]
in the after method of the state machine
Plan Load (0.1ms) SELECT "plans".* FROM "plans" WHERE "plans"."id" = $1 LIMIT 1 [["id", 2]]
SQL (0.2ms) UPDATE "users" SET "plan_start_date" = $1, "updated_at" = $2 WHERE "users"."type" IN ('Presenter') AND "users"."id" = 20 [["plan_start_date", "2016-02-26 20:06:29.310158"], ["updated_at", "2016-02-26 20:06:29.311003"]]
resource saved
charge built
before call_braintree
in call braintree
braintree error
(0.2ms) ROLLBACK
ichabod is yolo
#charge #<Charge id: nil, user_id: 20, stripe_id: nil, created_at: "2016-02-26 20:06:29", updated_at: "2016-02-26 20:06:29">
#charge errors: #<ActiveModel::Errors:0x007ffac3f16790 #base=#<Charge id: nil, user_id: 20, stripe_id: nil, created_at: "2016-02-26 20:06:29", updated_at: "2016-02-26 20:06:29">, #messages={}>
resource did not persist
NOW WE KNOW
Rendered layouts/logged_in/_error_messages.html.erb (0.0ms)
#type is Presenter
#free_trial is
in here
Plan Load (0.3ms) SELECT "plans".* FROM "plans" WHERE "plans"."user_type" = 'Presenter' AND ("plans"."name" != 'free_trial') ORDER BY "plans"."display_order_number" ASC
Rendered layouts/logged_in/_registration_form_header.html.erb (1.7ms)
Rendered layouts/logged_in/_payment_form.html.erb (0.1ms)
Rendered layouts/logged_in/_registration_submit_button.html.erb (0.1ms)
Rendered charges/_braintree_js.html.erb (0.0ms)
Rendered devise/registrations/new.html.erb within layouts/logged_in (8.3ms)
Rendered layouts/logged_in/_navbar.html.erb (0.4ms)
resource errors are #<ActiveModel::Errors:0x007ffac3fd6ae0 #base=#<Presenter id: nil, email: "asfdjhfasdlk#dffadsdf.com", encrypted_password: "$2a$10$jeIa3c.i73f/hBV7ne/Dfu0MAawQzoNak808zLqjjkF...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-02-26 20:06:29", updated_at: "2016-02-26 20:06:29", confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, organization_id: nil, type: "Presenter", organization_name: "", organization_code: nil, identifier: nil, stripe_customer_id: nil, plan_id: 2, presenter_maximum: nil, workshop_id: nil, presentation_allowance: 2, plan_status: "active", plan_start_date: "2016-02-26 20:06:29", plan_length: 1, contact_name: nil, contact_phone: nil, first_name: "david", last_name: "applebaum", telephone: "6462343800", group_id: nil>, #messages={:plan_id=>[], :organization_name=>[], :first_name=>[], :last_name=>[], :email=>[], :password=>[], :password_confirmation=>[], :telephone=>[], :group_code=>[]}>
Completed 200 OK in 2171ms (Views: 81.0ms | ActiveRecord: 1.8ms)
The only thing I did differently in order to get a braintree error was switch the amount in the call_braintree method with 2600.
As you can see in the logs, some type of error was thrown or the call was not a success, and yet Braintree did not provide an error. Whenever the users card does not work, for whatever reason, I need an error message from braintree to show the user. How do I get braintree errors to properly display?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact our support team.
Errors are only populated for Braintree validation errors. Processor errors are reported in the Transaction's processor_response_code
Appropriate error handling for Transactions that fail at the processor level would look like this:
if braintree_call.success? && !braintree_call.errors.any?
puts "braintree_call was a success".green
#charge.save
#do nothing. All good
elsif braintree_call.transaction
puts "Transaction processing error: #{braintree_call.transaction.status}: Response Code: #{braintree_call.transaction.processor_response_code}\n".red
raise "#Charge Failed"
else
puts "braintree error".red
#braintree_errors = braintree_call.errors
braintree_call.errors.each do |error|
puts "#{error.code}\n".red
puts "#{error.message}".red
end
raise "#Charge Failed"
end
Check out our docs for more info on transaction statuses and processor response codes

undefined method with has_many association

I have 2 models with a one-to-many association: User and Recipe. the User class has_many :recipes while the Recipe class belongs_to :user. I've already run the migration, reloaded the rails console, and checked to make sure that user_id is a column in the recipes table. Still, I get an undefined method error when I try to append a recipe to a user:
2.0.0-p598 :047 > user.recipes << Recipe.first
NoMethodError: undefined method `recipes' for #<User:0x00000004326fa0>
here is the migration code (I've already run rake db:migrate):
class AddUserIdToRecipes < ActiveRecord::Migration
def change
add_column :recipes, :user_id, :integer
end
end
Here is the User model code:
class User < ActiveRecord::Base
has_one :profile
has_many :recipes
end
Here is the Recipe model code:
class Recipe < ActiveRecord::Base
validates_presence_of :title, :body
belongs_to :user
def long_title
"#{title} - #{published_at}"
end
end
Why does recipes still show up as an undefined method?
Try this on your console:
irb(main):007:0> user = User.new first_name: 'John', last_name: 'Doe'
=> #<User id: nil, first_name: "John", last_name: "Doe", created_at: nil, updated_at: nil>
irb(main):008:0> user.save
(0.1ms) begin transaction
SQL (0.6ms) INSERT INTO "users" ("created_at", "first_name", "last_name", "updated_at") VALUES (?, ?, ?, ?) [["created_at", "2015-01-19 21:14:33.489371"], ["first_name", "John"], ["last_name", "Doe"], ["updated_at", "2015-01-19 21:14:33.489371"]]
(0.6ms) commit transaction
=> true
irb(main):009:0> r = Recipe.new name: 'oooohh awesome', description: 'my description goes here'
=> #<Recipe id: nil, name: "oooohh awesome", description: "my description goes here", created_at: nil, updated_at: nil, user_id: nil>
irb(main):010:0> r.save
(0.1ms) begin transaction
SQL (0.2ms) INSERT INTO "recipes" ("created_at", "description", "name", "updated_at") VALUES (?, ?, ?, ?) [["created_at", "2015-01-19 21:15:16.548090"], ["description", "my description goes here"], ["name", "oooohh awesome"], ["updated_at", "2015-01-19 21:15:16.548090"]]
(1.2ms) commit transaction
=> true
irb(main):011:0> user.recipes << Recipe.first
Recipe Load (0.2ms) SELECT "recipes".* FROM "recipes" ORDER BY "recipes"."id" ASC LIMIT 1
(0.0ms) begin transaction
SQL (0.2ms) UPDATE "recipes" SET "updated_at" = ?, "user_id" = ? WHERE "recipes"."id" = 1 [["updated_at", "2015-01-19 21:15:49.181586"], ["user_id", 1]]
(1.3ms) commit transaction
Recipe Load (0.2ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."user_id" = ? [["user_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Recipe id: 1, name: "oooohh awesome", description: "sper long deskdk", created_at: "2015-01-19 21:10:24", updated_at: "2015-01-19 21:15:49", user_id: 1>]>
irb(main):012:0> user.save
(0.1ms) begin transaction
(0.0ms) commit transaction
=> true
irb(main):013:0> user.recipes
=> #<ActiveRecord::Associations::CollectionProxy [#<Recipe id: 1, name: "oooohh awesome", description: "sper long deskdk", created_at: "2015-01-19 21:10:24", updated_at: "2015-01-19 21:15:49", user_id: 1>]>
irb(main):014:0> user.recipes.first
=> #<Recipe id: 1, name: "oooohh awesome", description: "sper long deskdk", created_at: "2015-01-19 21:10:24", updated_at: "2015-01-19 21:15:49", user_id: 1>
irb(main):015:0>
you can see that Recipe.first has been inserted into user.recipes and its saved.
I made two models similar to yours, and have exactly the same setup as you. You can follow code above to write your controllers.

Has_many :through reversed access?

Not exactly an error, but I think I am missing something important here..
class Team < ActiveRecord::Base
has_many :groups
has_many :users, :through => :groups
class User < ActiveRecord::Base
acts_as_authentic
has_many :groups
has_many :teams, :through => :groups
class Group < ActiveRecord::Base
belongs_to :user
belongs_to :team
So I can do something like:
user_test.teams << team_test
and I expect that after that I should be able to do something like:
team_test.users
it will list user_test among all others.. But it does not..
What am I missing?
Thanks!
EDIT::
ruby-1.9.3-p0 :001 > user_test = User.create
(0.0ms) SAVEPOINT active_record_1
(0.1ms) SELECT 1 FROM "users" WHERE "users"."persistence_token" = '6f2890df599776198476630fad3db57b62606339d7ec2c1e96cc4081919789fa0a7cac5ffaed6b8f61f28f3ff2abd6ca890eb623c1b2d6718328d10527fa1566' LIMIT 1
(0.0ms) ROLLBACK TO SAVEPOINT active_record_1
=> #<User id: nil, username: nil, email: nil, crypted_password: nil, password_salt: nil, persistence_token: "6f2890df599776198476630fad3db57b62606339d7ec2c1e96c...", created_at: nil, updated_at: nil>
ruby-1.9.3-p0 :002 > team_test = Team.create
(0.0ms) SAVEPOINT active_record_1
SQL (1.9ms) INSERT INTO "teams" ("created_at", "name", "personal", "project_id", "updated_at", "visible") VALUES (?, ?, ?, ?, ?, ?) [["created_at", Tue, 22 Nov 2011 23:09:28 UTC +00:00], ["name", nil], ["personal", false], ["project_id", nil], ["updated_at", Tue, 22 Nov 2011 23:09:28 UTC +00:00], ["visible", nil]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> #<Team id: 8, name: nil, created_at: "2011-11-22 23:09:28", updated_at: "2011-11-22 23:09:28", visible: nil, personal: false, project_id: nil>
ruby-1.9.3-p0 :003 > user_test.teams << team_test
(0.1ms) SAVEPOINT active_record_1
(0.0ms) RELEASE SAVEPOINT active_record_1
=> [#<Team id: 8, name: nil, created_at: "2011-11-22 23:09:28", updated_at: "2011-11-22 23:09:28", visible: nil, personal: false, project_id: nil>]
ruby-1.9.3-p0 :004 > user_test.teams
=> [#<Team id: 8, name: nil, created_at: "2011-11-22 23:09:28", updated_at: "2011-11-22 23:09:28", visible: nil, personal: false, project_id: nil>]
ruby-1.9.3-p0 :005 > team_test.users
User Load (0.1ms) SELECT "users".* FROM "users" INNER JOIN "groups" ON "users"."id" = "groups"."user_id" WHERE "groups"."team_id" = 8
=> []
This is strange... Are user_test and team_test saved or only initialized?
1/ the both are saved:
user_test = User.create
team_test = Team.create
user_test.teams << team_test
user_test.teams # => team_test among others
team_test.users # => user_test among others
2/ only one is saved:
a) the saved model is the one which 'received' the other:
user = User.create
team = Team.new
user.teams << team
# team is saved automatically
user.teams # => team among others
team.users # => user among others (because team was saved automatically)
b) the saved model is the one which 'is received' by the other:
user = User.new
team = Team.create
user.teams << team
user.teams # => return team
team.users # => [] (empty array; the 'receiver' is not saved automatically)
3/ none is saved
user = User.new
team = Team.new
users.teams << team
user.teams # => team but not saved (i.e. id is nil)
team.users # => [] (empty array)
You might be in case 2.b or in case 3.

Resources