after_save error in ruby on rails - ruby-on-rails

I have two models linked to each other and I am trying to do an after_save, create in the model and code is as follows.
class CustomerBill < ActiveRecord::Base
after_save :updating_and_creating_ledger_items
has_many :customer_ledgers, :dependent => :destroy
def updating_and_creating_ledger_items
CustomerLedger.create(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)
end
end
customer ledger model
class CustomerLedger < ActiveRecord::Base
belongs_to :customer_bill, :foreign_key => "customer_bill_id"
end
Now the problem is the program executes perfectly but the value are not been put in the database. If I check Customer ledger it is still empty.
The values are not getting stored. what seems to be the problem? Guidance towards this matter will be helpful.
Thanks in advance. :)

Add
validates_associated :customer_ledgers
In customer_bill.rb
Try
ledger = customer_ledgers.build(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)
ledger.save
EDITED for to avoid Validations, use
ledger = customer_ledgers.build(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)
ledger.save(:validate => false)

The CustomerLedger may be failing a validation check. Replace:
def updating_and_creating_ledger_items
CustomerLedger.create(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)
end
with:
def updating_and_creating_ledger_items
ledger = customer_ledgers.build(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)
ledger.save(:validate => false)
end

You're not setting the customer_bill_id in the create, change create to build as so:
customer_ledger.build(:date => self.date, :customer_id => self.customer_id, :user_id => self.user_id)

Related

Unknown key find_options during database migration

I'm trying to update an old Redmine plugin but when I try to do the migration I get this error. Could someone give me some pointers how to address the problem?
I tried to replace find_options with scope but I'm not exactly sure how do to it.
rake aborted!
ArgumentError: Unknown key: :find_options. Valid keys are: :type, :permission, :timestamp, :author_key, :scope
/home/developer/projects/redmine/redmine-3.3.1/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb:32:in `acts_as_activity_provider'
Migration file:
require File.join(File.dirname(__FILE__), '../../app/models', 'hudson_build')
class UpdateBuilding < ActiveRecord::Migration
def self.up
HudsonBuild.update_all "building = 'true'", "building = 't'"
HudsonBuild.update_all "building = 'false'", "building = 'f'"
end
def self.down
HudsonBuild.update_all "building = 't'", "building = 'true'"
HudsonBuild.update_all "building = 'f'", "building = 'false'"
end
end
part of my hudson_build.rb model that's causing the problem:
require 'hudson_api_error'
require 'hudson_exceptions'
require 'rexml_helper'
include RexmlHelper
class HudsonBuild < ActiveRecord::Base
unloadable
has_many :changesets, :class_name => 'HudsonBuildChangeset', :dependent => :destroy
has_one :test_result, :class_name => 'HudsonBuildTestResult', :dependent => :destroy
has_many :artifacts, :class_name => 'HudsonBuildArtifact', :dependent => :destroy
belongs_to :job, :class_name => 'HudsonJob', :foreign_key => 'hudson_job_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'caused_by'
validates_presence_of :hudson_job_id, :number
validates_uniqueness_of :number, :scope => :hudson_job_id
acts_as_event :title => Proc.new {|o|
retval = "#{l(:label_build)} #{o.job.name} #{o.number}: #{o.result}" unless o.building?
retval = "#{l(:label_build)} #{o.job.name} #{o.number}: #{l(:notice_building)}" if o.building?
retval
},
:description => Proc.new{|o|
items = []
items << o.test_result.description_for_activity if o.test_result != nil
items << HudsonBuildChangeset.description_for_activity(o.changesets) if o.changesets.length > 0
items.join("; ")
},
:datetime => :finished_at
acts_as_activity_provider :type => 'hudson',
:timestamp => "#{HudsonBuild.table_name}.finished_at",
:author_key => "#{HudsonBuild.table_name}.caused_by",
:find_options => {:include => {:job => :project}},
:permission => :view_hudson
include HudsonHelper
extend RexmlHelper
I don't know this plugin but i found this commit
Please try changing in HudsonBuild class this line:
:find_options => {:include => {:job => :project}},
to
:scope => includes(:project),
Here is an example.

How to create a record through, has many association with two foreign keys.

I need to create a route which is associated to a location.
class Location < ActiveRecord::Base
has_many :routes,:foreign_key => "origin_id"
end
and a route belongs to different locations:
class Route < ActiveRecord::Base
belongs_to :origin, :class_name => 'Location', :foreign_key => 'location_id'
belongs_to :destination, :class_name => 'Location', :foreign_key => 'destination_id'
validates :origin, :presence => {:message => 'origin cannot be blank'}
end
location.routes.create({
:destination => resort_location,
:destination_id => resort_location.id,
:total_distance => body['route_summary']['total_distance'],
:total_time => body['route_summary']['total_time'],
:raw => response.body
})
Records get create without origin and destination, even though I do have the presence validation.
Thanks for helping me out.
Code looks okay to me -
location.routes.create({
:destination => resort_location, #-> where is resort_location defined?
:destination_id => resort_location.id,
:total_distance => body['route_summary']['total_distance'],
:total_time => body['route_summary']['total_time'],
:raw => response.body
})
Your validates method also needs to be for a specific attribute (not a relation). In your case, it should be like this:
validates :location_id, presence: {message: 'You need an origin!'}
Do you have any errors / logs for this?

Rails 3.1: Trying to update ActiveRecord: NoMethodError: undefined method `keys' for #<ActiveRecord::Relation:0x007fdfb82aca98>

I'm trying to update an ActiveRecord, which seems like it SHOULD be easy enough. Methods I've tried in my
Controller (metadata_controller.rb):
def update_metadata_type
#metadata_type = MetadataType.find(params[:id])
if #metadata_type.update_attributes(params)
render :template => 'metadata/show_metadata_type'
else
# return error template
end
end
def update_metadata_type
if MetadataType.update(1, { :name => params[:name] })
render :template => 'metadata/show_metadata_type'
else
# return error template
end
end
def update_metadata_type
#metadata_type = MetadataType.find(params[:id])
#metadata_type.name = params[:name]
#metadata_type.save
render :template => 'metadata/show_metadata_type'
end
Model (metadata_type.rb):
class MetadataType < ActiveRecord::Base
has_many :metadata_type_attributes, :dependent => :destroy
has_many :attributes, :through => :metadata_type_attributes, :dependent => :destroy
attr_accessible :name, :attribute_type_id
validates :name, :uniqueness => true
end
Different model with same problem (attribute_type.rb):
class AttributeType < ActiveRecord::Base
belongs_to :attributes
attr_accessible :data_type
validates :data_type, :uniqueness => true
end
routes.rb:
match '/metadata_type/:id' => 'metadata#update_metadata_type', :via => [:put], :as => 'update_metadata_type'
Each time I'm sending the data using RESTClient, with the appropriate headers to send json, with the following data in a PUT command:
{
"name" : "NewName"
}
I've also used binding.pry in the controller to make sure #metadata_type is found (and not nil) and it always looks right:
[1] pry(#<MetadataController>)> #metadata_type = MetadataType.find(params[:id])
=> #<MetadataType id: 1, name: "Category", created_at: "2011-11-15 16:02:53", updated_at: "2011-11-15 16:02:53">
Params also looks right:
[7] pry(#<MetadataController>)> params
=> {"name"=>"NewName",
"controller"=>"metadata",
"action"=>"update_metadata_type",
"id"=>"1",
"metadatum"=>{"name"=>"NewName"}}
But for some reason, no matter how I try and save, I get the same error:
NoMethodError (undefined method `keys' for #<ActiveRecord::Relation:0x007fdfb7637fd8>):
app/controllers/metadata_controller.rb:50:in `update_metadata_type'
Any idea on what's causing this? All help is appreciated
Sorry I'm a little late to the party but you can't define an association with the name attributes as it ends up overriding the built in attributes accessor method defined and used by ActiveRecord itself.
Well hopefully this helps anyone else who happens to come across this obscure error.
The problem is with these lines:
has_many :metadata_type_attributes, :dependent => :destroy
has_many :attributes, :through => :metadata_type_attributes, :dependent => :destroy
I'm a little confused as to what exactly you're trying to do, but I suspect you mean:
has_many :attributes, :class_name => "MetadataTypeAttributes", :dependent => :destroy

Updating object with belongs_to associations and nested_attributes

I've got problems with making update action for one of my data objects. I've got:
class UserProfile < ActiveRecord::Base
belongs_to :address, :dependent => :destroy
belongs_to :post_address, :class_name => 'Address', :dependent => :destroy
accepts_nested_attributes_for :address
accepts_nested_attributes_for :post_address
# validations and stuff
end
class Address < ActiveRecord::Base
# validations and stuff
end
And the problem is with the form and action:
= form_for #up, :url => '/profile/edit', :method => :post do |f|
= f.error_messages
#...
= f.fields_for :address, #up.address do |a|
#...
= f.fields_for :post_address, #up.post_address do |a|
#...
.field.push
= f.submit 'Save', :class=>'ok'
Action:
def edit_account
#user = current_user
if request.post?
#up = #user.user_profile.update_attributes(params[:user_profile])
if #up.save
redirect_to '/profile/data', :notice => 'Zmiana danych przebiegła pomyślnie.'
end
else
#up = #user.user_profile
end
end
The error I get looks like this:
Couldn't find Address with ID=3 for UserProfile with ID=2
And it occurs in the line:
#up = #user.user_profile.update_attributes(params[:user_profile])
I think that AR tries to create another Address when the form is submitted but I'm not certain.
Why do I get this error? What's wrong with my code?
So not sure how that works on new since #up.address is nil. Can you try something like:
=f.fields_for :address, (#up.address.nil? ? Address.new() : #up.address) do |a|
#...
= f.fields_for :post_address, (#up.post_address.nil? Address.new() : #up.post_address) do |a|
#...
That might make a difference?
Solved
I just changed the type of association in UserProfile:
has_one :address,
:class_name => 'Address',
:foreign_key => 'user_profile_id',
:conditions => {:is_post => false},
:dependent => :destroy
has_one :post_address,
:class_name => 'Address',
:foreign_key => 'user_profile_id',
:conditions => {:is_post => true},
:dependent => :destroy,
:validate => false
And slightly adjusted the controller. Thanks for help!

How do I make a grouped select box grouped by a column for a given model in Formtastic for Rails?

In my Rails project I'm using Formtastic to manage my forms. I have a model, Tags, with a column, "group". The group column is just a simple hardcoded way to organize my tags. I will post my Tag model class so you can see how it's organized
class Tag < ActiveRecord::Base
class Group
BRAND = 1
SEASON = 2
OCCASION = 3
CONDITION = 4
SUBCATEGORY = 5
end
has_many :taggings, :dependent => :destroy
has_many :plaggs, :through => :taggings
has_many :monitorings, :as => :monitorizable
validates_presence_of :name, :group
validates_uniqueness_of :name, :case_sensitive => false
def self.brands(options = {})
self.all({ :conditions => { :group => Group::BRAND } }.merge(options))
end
def self.seasons(options = {})
self.all({ :conditions => { :group => Group::SEASON } }.merge(options))
end
def self.occasions(options = {})
self.all({ :conditions => { :group => Group::OCCASION } }.merge(options))
end
def self.conditions(options = {})
self.all({ :conditions => { :group => Group::CONDITION } }.merge(options))
end
def self.subcategories(options = {})
self.all({ :conditions => { :group => Group::SUBCATEGORY } }.merge(options))
end
def self.non_brands(options = {})
self.all({ :conditions => [ "`group` != ? AND `group` != ?", Tag::Group::SUBCATEGORY, Tag::Group::BRAND] }.merge(options))
end
end
My goal is to use Formtastic to provide a grouped multiselect box, grouped by the column, "group" with the tags that are returned from the non_brands method. I have tried the following:
= f.input :tags, :required => false, :as => :select, :input_html => { :multiple => true }, :collection => tags, :selected => sel_tags, :group_by => :group, :prompt => false
But I receive the following error:
(undefined method `klass' for
nil:NilClass)
Any ideas where I'm going wrong?
Thanks for looking :]
I'm not sure we support :group_by with a custom :collection. In fact, that who part of the code was a messy contribution. So, try omitting the :collection for starters, and see where you end up. If there's a bug with Formtastic, please add an issue on Github.
I'd first move your Group class out of this file, and just inherit from where you want, or use a Module in this class. This is the preferred way of getting methods an constants into a class and staying organized.

Resources