Why wont counter_cache work - ruby-on-rails

class FixedLineItem < AR
belongs_to :fee_table, :class_name => 'FixedFeeTable',
:foreign_key => 'fixed_fee_table_id',
:inverse_of => :line_items,
:counter_cache => :fixed_line_items_count
end
class FixedFeeTable < AR
has_many :line_items, :class_name => 'FixedLineItem',
:inverse_of => :fee_table
end
Given the above, why does #fixed_fee_table.line_items.size still access the db? I can see it performing a COUNT operation in the console.
If i rename the has_many association to has_many :fixed_line_items, it works as expected.
Am i missing an option somewhere? I cant find any mention through googling however.
EDIT
This is on rails 3.2.14
and my schema for the two tables
create_table "fixed_fee_tables", :force => true do |t|
t.string "kind"
t.integer "total_amount_cents"
t.integer "fee_summary_id"
t.string "currency"
t.integer "final_total_amount_cents"
t.integer "fixed_line_items_count", :default => 0, :null => false
end
create_table "fixed_line_items", :force => true do |t|
t.string "description"
t.integer "quantity"
t.integer "price_cents"
t.integer "fixed_fee_table_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "amount_cents"
t.integer "position"
t.integer "total_adjustment_cents"
t.string "currency"
end

Related

Rails uniqueness validation based on relation

I have two models...
create_table "registrations", :force => true do |t|
t.integer "orientation_id"
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "student_id"
...
end
create_table "orientations", :force => true do |t|
t.date "class_date"
t.text "class_time"
t.integer "seats"
t.boolean "active", :default => true
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I want to create a validation in my registration model that says the student_id must be unique in each Orientation.
If i understood your question correctly,you want the scope option of the validates_uniqueness_of.If so,this should work
In your Registration model,
Class Registration < ActiveRecord::Base
......
validates_uniqueness_of :student_id, scope: :orientation_id
end
And also,you should be generating a migration to add this
add_index :registration, [ :student_id, :orientation_id ], :unique => true
More Info here

Why does only one of my has_many though models work

I followed http://railscasts.com/episodes/17-habtm-checkboxes-revised?view=asciicast tutorial to set up a has_many through relationship and when I try to access information from one model it works but not from the other.
I can access the Category information from the Product model via #product.category_ids and #product.categories, but the reverse isn't true. I can't access the Product information from the Category model. Using #category.product_ids or #category.products gives me the error NoMethodError: undefined method 'product_ids' for #<Category:0x007fa70d430e98>
Product.rb
class Product < ActiveRecord::Base
attr_accessible :category_ids
has_many :categorizations
has_many :categories, through: :categorizations
accepts_nested_attributes_for :categorizations, :allow_destroy => true
end
Category.rb
class Category < ActiveRecord::Base
attr_accessible :product_ids
has_many :categorizations
has_many :products, through: :categorizations
end
-- EDIT --
Schema.rb
ActiveRecord::Schema.define(:version => 20130926192205) do
create_table "categories", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "products", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "categorization", :force => true do |t|
t.integer "product_id"
t.integer "category_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "categorization", ["product_id", "category_id"], :name => "index_categorization_on_product_id_and_category_id", :unique => true
add_index "categorization", ["product_id"], :name => "index_categorization_on_product_id"
add_index "categorization", ["category_id"], :name => "index_categorization_on_category_id"
end
To access the records from each object you should be able to:
#category.products
and
#product.categories
That will give you the associated objects.
product_ids is not a attribute on a category and it does not have accepts_attributes_for :products like your category model so removing attr_accessible :product_ids should fix the error.

Rails ActiveRecord has_many through not working

I have a rails app where users have children. So I had two models: :users and :children.
I used to have a one-to-many relationship (has_many / belongs_to), but I wanted to open it up to a many-to-many relationship where I could store variables about the relationship. So I changed the relationship to a "has_many through" relationship. I created a table called :relationships. A small caveat: I want the foreign_key for user to be :parent_id. Here is how I have them set up:
Schema:
create_table "relationships", :force => true do |t|
t.integer "child_id"
t.integer "parent_id"
t.datetime "created_at"
.
.
.
create_table "users", :force => true do |t|
t.string "email", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "first_name"
t.string "last_name"
.
.
.
create_table "children", :force => true do |t|
t.string "name", :null => false
t.integer "parent_id", :null => false
t.datetime "created_at", :null => false
.
.
.
Class Definitions:
user.rb:
has_many :relationships, foreign_key: "parent_id"
has_many :children, :through => :relationships, foreign_key: "parent_id"
child.rb:
has_many :relationships, foreign_key: "child_id"
has_many :parents, :through => :relationships
relationship.rb:
belongs_to :parent, class_name: "User", :foreign_key => :parent_id
belongs_to :child, class_name: "Child", :foreign_key => :child_id
Now when I choose a specific user and try to get user.children, I get [] in response. If I try to add new children, it doesn't work either. I can define the parent and the child, but when it tries to save, It cannot associate the two. It doesn't see the parent, so I get the error:
*ActiveRecord::StatementInvalid (PG::Error: ERROR: null value in column "parent_id" violates not-null constraint*
If I switch the Class definitions back to a one-to-many setup, it accesses the children just fine. I don't understand what the problem is. Any help would be very appreciated.
Thanks
How are you building the relationship? #user.children works for me with the given example when I create the relationship as follows:
#user.relationships.build(child_id: ...)
in children table parent_id should be allowed to take null if you want create children as nested attributes.
Change
create_table "children", :force => true do |t|
t.string "name", :null => false
t.integer "parent_id", :null => false
t.datetime "created_at", :null => false
end
To
create_table "children", :force => true do |t|
t.string "name", :null => false
t.integer "parent_id"
t.datetime "created_at", :null => false
end

Sorting based on column in join model in Rails

I followed this RailsCast to make a sortable list of items, which works great for one model, but I need to sort items that are organized by a join model, and can't figure out how to do it. Here is an example:
I want to organize all the cycles that are in a program by the cycle_order column.
The cycle_order column is in the cycles_programs table
For good measure, see picture of the join table at the bottom.
class Cycle
has_many :cycles_programs
has_many :programs, :through => :cycles_programs
accepts_nested_attributes_for :programs
accepts_nested_attributes_for :cycles_programs, allow_destroy: :true
class CyclesProgram
belongs_to :program
belongs_to :cycle
class Program
has_many :cycles_programs
has_many :cycles, :through => :cycles_programs
accepts_nested_attributes_for :cycles
accepts_nested_attributes_for :cycles_programs, allow_destroy: :true
Here is the Schema:
create_table "programs", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "cycles_programs", :force => true do |t|
t.integer "program_id"
t.integer "cycle_id"
t.integer "cycle_order"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "cycles", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
Add a default scope to CyclesGroup
default_scope -> { order(:group_order) }
And the answer is so simple. Just add default_scope -> { order(:cycle)order) } to the CyclesProgram model

How to perform a query over models with attributes stored in other models?

I have the following models:
class Constraint < ActiveRecord::Base
belongs_to :constraint_category
end
class ConstraintCategory < ActiveRecord::Base
has_many :constraints
end
The models have these attributes (from db/schema.rb):
create_table "constraint_categories", :force => true do |t|
t.string "value"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "active"
end
create_table "constraints", :force => true do |t|
t.string "phrase"
t.integer "constraint_category_id", :limit => 255
t.boolean "active"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I would like to create a query that finds all constraints where the "active" attribute is "true" and the "constraint_category.value" is "Noun".
Would love any advice on getting there.
Constraint.joins(:constraint_category).where('constraints.active = ? and constraint_categories.value = ?', true, 'Noun')
See conditions and joins in the guide.

Resources