polymorphic model but want multiple versions of it - ruby-on-rails-3

I have a polymorphic asset model but would like two different versions of it for an asset class. Something like:
class Location < ActiveRecord::Base
has_many :assets, :as => :assetable, :order => 'position'
has_many :assets :known_as => :cover_images, :as => :assetable, :order => 'position'
I saw this question: Rails Polymorphic Association with multiple associations on the same model but when I implemented in Rails 3.1 with my models, it looked like:
has_many :assets, :as => :assetable, :order => 'position'
has_one :header_photo, :class_name => 'Asset', :as => 'assetable', :conditions => {:assetable_type => 'header_asset'}, :dependent => :destroy
Looking in console, I see:
SELECT `assets`.* FROM `assets` WHERE `assets`.`assetable_id` = 37 AND `assets`.`assetable_type` = 'Location' AND `assets`.`assetable_type` = 'header_asset' LIMIT 1
which is not what I want.
How would I do this? Is there syntax for handling this?
thx

Related

rails 5 way for having order and includes in has_many

I have this line in rails 3:
has_many :balance_lines, :dependent => :destroy, :include => "budget_item", :order => "budget_items.position"
How do I convert it to rails 5?
This is the right way:
has_many :balance_lines, -> { order("budget_items.position").includes("budget_item") }, :dependent => :destroy

How should I model horse pedigrees in rails?

I need to model up to 5 or 6 generations horse pedigrees using rails/activerecord. I did my research here on stack and on the web and ultimately utilized this article as the basis of my approach. Here's what I've come up with.
Two models:
Horse has the following attributes id and horse_name
Pedigree has: id, parent_id and horse_id.
And the following associations:
has_many :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy
has_one :sire_horse_relationship, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Male'
has_one :dam_horse_relationship, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Female'
has_many :parents, :through => :parent_horse_relationships, :source => :parent
has_one :sire, :through => :sire_horse_relationship,:source => :parent
has_one :dam, :through => :dam_horse_relationship,:source => :parent
has_many :horse_parent_relationships, :class_name => "Pedigree", :foreign_key => :parent_id, :dependent => :destroy
has_many :progenies, :through => :horse_parent_relationships, :source => :horse
This approach is close, however it appears my condition to determine the dam or sire is being applied to the Horse and not the parent. Therefore if the particular horse is Male, the horse.sire will work, but the horse.dam will not and vice versa. Once I get basic functionality working I'd like to add additional methods to get the whole pedigree, grandparents, siblings, descendants, etc.
Questions:
How can I apply the gender condition to the parents and not the horse so that both sire and dam work.
Is the approach that I have take viable or is there a more elegant, efficient way of accomplishing this.
Any other suggestions or guidance would be appreciated.
Apologies for the long question and thanks for your help.
I might start with:
has_one :sire, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Male'
has_one :dam, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Female'
has_many :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy
has_many :parents, :through => :parent_horse_relationships, :source => :parent
has_many :progenies, :through => :horse_parent_relationships, :source => :horse
I ended up spending a great deal of time on this one, but finally came up with a solution that met my requirements. The associations that ultimately worked follow:
has_many :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy
has_many :parents, :through => :parent_horse_relationships, :source => :parent do
def dam_relationship
owner = self.proxy_association.owner
owner = owner.parents.where(:horse_gender => "Female")
where('pedigrees.parent_id = ?', owner)
end
def sire_relationship
owner = self.proxy_association.owner
owner = owner.parents.where(:horse_gender => "Male")
where('pedigrees.parent_id = ?', owner)
end
end
def dam
parents.dam_relationship
end
def sire
parents.sire_relationship
end
Question responses:
I applied the gender condition through use of an association_proxy and a simple wrapper. I created a dam_relationship and corresponding sire_relationship and then wrapped those methods in a couple of dam and sire wrapper methods.
def dam_relationship
owner = self.proxy_association.owner
owner = owner.parents.where(:horse_gender => "Female")
where('pedigrees.parent_id = ?', owner)
end
def dam
parents.dam_relationship
end
This allows me to do:
#horse.parents, #horse.dam, #horse.sire (not displayed)
as well as most of the methods included in the ancestry gem mentioned below. With a little bit of recursion it's fairly straight forward to display the entire pedigree or the number of generations that interest you.
I decided that the approach of having two models (Horse and Pedigree) provide som additional flexibility compared to having the sire_id and dam_id directly in the Horse model. This approach will enable me to more easily create methods like #horse.uncle, #horse.aunt. I believe these would be more difficult with the sire_id and dam_id directly in the Horse model.
The most popular gem for accomplishing this seems to be ancestry. The author accomplishes this and a lot more simply by adding an ancestry column to the model of interest. Its a very nice solution a definitely worth checking out.

How to customize formtastic attribute :as=>:check_boxes

my problem is that I try to customize the formatastic view. But before I go into detail, I'll explain my model.
I have 2 objects with a n:m relation Shop and Category
Shop model looks like that:
has_many :shop_categories, :class_name => "ShopCategory", :foreign_key => "shop_id"
has_many :categories, :through => :shop_categories, :source => :categories
Category model looks like that:
has_many :shop_categories, :class_name => "ShopCategory", :foreign_key => "category_id"
has_many :shops, :through => :shop_categories, :source => :shops
And of course my m to n table looks like
belongs_to :shops, :class_name => "Shop", :foreign_key => "shop_id"
belongs_to :categories, :class_name => "Category", :foreign_key => "category_id"
validates :shop_id, :presence => true
validates :category_id, :presence => true
This works fine and the following command in my Shop view will list all elements from categories within checkboxes:
<%= f.input :categories, :as => :check_boxes, :id => 'shop_categories' %>
Here is my problem:
Within categories I have a name for the category and a picture. Now I want to display the picture next to the selectbox.
I also tryed to use <% f.fields_for :categories do |category| %> but rails wont go through all category elements.
Is there a way to handle all Category elements with automatic checked objects?
If you need more information, i will be glad to give all what you need to understand the problem.
Thank you for any hint.
Try overriding custom inputs:
# app/inputs/collection_check_boxes_input.rb
class CollectionCheckBoxesInput < SimpleForm::Inputs::CollectionCheckBoxesInput
# [...]
end

Scoped mass assignment and accepts_nested_attributes_for in Rails 3.1 not working?

Using Rails 3.1 RC4.
My User model has the following:
has_many :emails, :dependent => :destroy
accepts_nested_attributes_for :emails
My Email model has the following:
belongs_to :user
attr_accessible :email, :email_confirmation, :as => :admin
In Rails console:
User.first.update_attributes!({:artist_name => 'foo', :emails_attributes => {0 => {:email => 'foo#blah.com', :email_confirmation => 'foo#foo.com'}}}, :as => :admin)
I get:
WARNING: Can't mass-assign protected attributes: email, email_confirmation
In my Email model, if I remove :as => :admin. Everything works...
Should I be assigning some kind of scope to accepts_nested_attributes_for? Anyone know how this can be fixed?
Issue and solution has been highlighted here.
In summary, an options hash must be passed.

Rails 3 has_many through scope with joins returns unexpected results

I am trying to create scopes to find all Galleries by a specific category type, like "Style". Eventually, they will be chained to filter by multiple category types, but I can't get the first to work.
Here are the models:
Gallery:
has_many :gallery_categories, :class_name => "GalleryCategories", :dependent => :destroy
has_many :categories, :through => gallery_categories
has_many :colors, :through => gallery_categories, :source => :category, :conditions => {:type => "Color"}
has_many :styles, :through => gallery_categories, :source => :category, :conditions => {:type => "Style"}
...and many more types of categories...
Category:
:has_many :gallery_categories
:has_many :galleries, :through => :gallery_categories
GalleryCategories:
:belongs_to :gallery
:belongs_to :category
I am trying to do something like this in Gallery:
:scope :by_style, lambda {|style| joins(:styles).where(:category => {:name => style})}
Then, for example, I run
Gallery.by_style("Contemporary")
And I am returned 181 Galleries when there are only 40 Galleries, and in this example there should only be one returned with the style "Contemporary".
Here is the resulting SQL:
SELECT `galleries`.* FROM `galleries` INNER JOIN `gallery_categories` ON `galleries`.`id` = `gallery_categories`.`gallery_id` INNER JOIN `categories` ON `categories`.`type` = 'Style' WHERE `categories`.`name` = 'Contemporary'
Any ideas? Thanks in advance.