Find and count all Profiles with object name of HABTM relationship - ruby-on-rails-3

In my Rails 3 app I have two models, Profile and Item. Each has a HABTM relationship with the other. In my Profile model, I have a method wish_items that creates an Array of that same name (wish_items). If an item contains the category "wish", it is added to the wish_items Array for that profile.
For the purpose of this question, say I have an item named "phone" with category "wish". What I'd like to do is be able to find and count all Profiles that have "phone" in their wish_items Array so I can render that count in a view. My code is below.
My Profile.rb model:
class Profile < ActiveRecord::Base
has_and_belongs_to_many :items
def wish_items
wish_items = Array.new
items.each do |item|
if item.category == "wish"
wish_items << item
end
end
return wish_items
end
end
My Item.rb model:
class Item < ActiveRecord::Base
has_and_belongs_to_many :profiles
end
I have a join table items_profiles for this relationship. Here is that migration:
class CreateItemsProfiles < ActiveRecord::Migration
def self.up
create_table :items_profiles, :id =>false do |t|
t.references :item
t.references :profile
end
end
...
end
I saw this previous question and gave the answer a try but got an error NameError: uninitialized constant phone. Here is the code I tried from that:
Profile.all(:include => :items, :conditions => ["items.name = ?", phone])
Specifically I put that code in the following:
<%= pluralize(Profile.all(:include => :items, :conditions => ["items.name = ?", phone])).count, "person") %>
How can I do this?

The above was failing because I didn't have phone in quotations. Simple. The following worked:
Profile.all(:include => :items, :conditions => ["items.name = ?", "phone"])
And pluralizing:
<%= pluralize(Profile.all(:include => :items, :conditions => ["items.name = ?", "phone"]).count, "person") %>

Related

How to query a Ruby on Rails object's nested attribute?

I have a User model and a Product model. The User has one product and the Product has one user. To create the User and Product models, I have a single form that creates both using nested attributes.
I am trying to create a search that can look for a User based on their name, email address or Product serial number. I have this working when looking up a User's name or email address, but I don't know how to go about looking up a User's Product by serial number in the same form.
So I'm trying to search User.last_name, User.email AND User.product.serial - cannot figure out how to go about this.
Here is my User model
class User < ActiveRecord::Base
has_many :products, dependent: :destroy
accepts_nested_attributes_for :products, :allow_destroy => true
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :last_name, presence: true
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }
def self.search(query)
where("last_name = ? OR email = ?", query, query)
end
end
And my Product model
class Product < ActiveRecord::Base
belongs_to :user
default_scope -> { order('created_at DESC') }
validates :serial, presence: true
end
My User view that contains the search field
<%= form_tag(users_path, method: "get", :id => "user_search_form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search users" %>
<%= submit_tag("Search", :name => nil ) %>
<% end %>
The relevant part of my Users controller
def index
if params[:search]
#users = User.search(params[:search]).order("created_at DESC").paginate(page: params[:page], :per_page => 30)
else
#users = User.paginate(page: params[:page], :per_page => 30)
#product = #users.product
end
end
You can do this:
def self.search(query)
joins(:products)
.where("last_name = :query OR email = :query OR products.serial = :query",
query: query)
end

Passing value from one model to another using a drop-down menu

Models:
product.rb:
class Product < ActiveRecord::Base
attr_accessible :cat_id, :id, :name
belongs_to :category
end
category.rb:
class Category < ActiveRecord::Base
attr_accessible :id, :name
has_many :products
end
Routes:
routes.rb
resources :categories do
resources :products
end
I want to add products to category. What to write in controller and view of product please help!
Please!! I am a beginner to rails!
If you want a drop-down menu:
In _file.html.haml
= label_tag :Category
= select_tag "product[category_id]", options_from_collection_for_select(#categories, :id,:name,#selected = #product[:category_id] :include_blank => true
In products_controller.rb:
before_filter :get_categories, :only => [:new,:edit]
def get_categories
#categories = Category.all
end
You can do as shown below,
If your path(url) should be like http://loaclhost:3000/category/1/produts, use id params from your url
Pass cateogry id into product view
form.erb
<%= f.hidden_field :cat_id , :value => <pass catogory id from routes url> %>
then follow usual create method ( Please inspect object whether cat_id created or not )
Now , you can access category value from cat_id of product.
Hope it will be useful.

Problems with a has_many - belongs_to association

My data is basically Gallery(s) have many Picture(s), and Picture(s) belong_to a gallery. the pictures table has the foreign_key 'gallery_id'.
Although I`ve used has_many and belongs_to associations before, so I am not sure what I am doing wrong.
These are my relevant models:
class Gallery < ActiveRecord::Base
attr_accessible :name
has_many :pictures
belongs_to :home
end
class Picture < ActiveRecord::Base
belongs_to :gallery
validates :image, :presence => true
mount_uploader :image, ImageUploader
end
If I do this:
gallery = Gallery.create(:name => 'some name')
picture = Picture.create(:name => 'some name' , :image => 'some_image')
picture.gallery = gallery
this is true:
picture.gallery == #gallery
but this isnt
gallery.pictures == [ picture ]
because gallery.pictures returns an empty array.
On the other hand, if I create the picture this way, everything works as expected:
picture = Picture.create(:name => 'some name' , :image => 'some_image', :gallery_id => gallery)
Why? What I am doing wrong? I am using Rails 3.1.1 and sqlite
it should work
gallery.pictures.create :name => 'some name' , :image => 'some_image'
When adding pictures to your gallery. Try doing the assignment the other way around.
gallery = Gallery.create(:name => 'some name')
picture = Picture.create(:name => 'some name' , :image => 'some_image')
gallery.pictures << picture
This will update the #pictures method to return the newly assigned picture.

Using Rails Gem Active Admin with Associations

I'm trying out the new Rails gem http://activeadmin.info/ and it's working great! However I can't find any documentation on how to use it across associations. For example:
class Membership < ActiveRecord::Base
belongs_to :course
belongs_to :person
class Course < ActiveRecord::Base
has_many :memberships
has_many :people, :through => :memberships
class Person < ActiveRecord::Base
has_many :memberships
has_many :courses, :through => :memberships
The membership join table includes some extra data as well (ie: attendance). I'm trying to show the membership with both the course and student name - and allow filtering / sorting on those names. As far as I have found, Active Admin doesn't work across associations. Has anyone else been successful in doing that, or found another gem that does? Thanks so much!
ingredient.rb
class Ingredient < ActiveRecord::Base
has_and_belongs_to_many :products, :join_table => :ingredients_products
end
product.rb
class Product < ActiveRecord::Base
has_and_belongs_to_many :ingredients, :join_table => :ingredients_products
end
don't forget the migrations for the joining table (:id to false!)
class CreateProductsIngredients < ActiveRecord::Migration
def self.up
create_table :ingredients_products,:id => false do |t|
t.integer :product_id
t.integer :ingredient_id
t.timestamps
end
end
def self.down
drop_table :products_ingredients
end
end
Now define the form in you ActiveAdmin resource, override the default
ActiveAdmin.register Product do
form do |f|
f.inputs "Details" do
f.input :product_name
f.input :brand
f.input :ingredients # don't forget this one!
end
end
I've been playing with ActiveAdmin for a while now, here's how I managed to get associations to work in Indexes and Forms.
I've just guessed some of your model columns below. Also note, in the form. The 'person' section will show all the columns for editing, whereas the 'course' section will just show the specified column.
ActiveAdmin.register User do
index do
column :id
column :name
column :attendance
column :person do |membership|
membership.person.name
end
column :course do |membership|
membership.course.name
end
default_actions
end
form do |f|
f.inputs "Membership" do
f.input :name
f.input :created_at
f.input :updated_at
end
f.inputs :name => "Person", :for => :person do |person|
person.inputs
end
f.inputs :name => "Course", :for => :course do |course|
course.input :name
end
f.buttons
end
end
I haven't tested this, but you should be able to apply these ideas to your case. It's working for mine.
Update: I've just read your question again and noted that you're wanting to be able to sort on the association column. I've just checked my implementation and this indeed is not working. My answer may be useless to you but I'll leave it here anyway (might help someone else).
I've just started using this gem myself, and while I haven't gotten around to showing association information, here's how you create a form for associations:
form do |f|
f.inputs
f.has_many :associations do |association|
association.inputs
end
f.buttons
end
That will give you a basic form with scaffolding.
ingredient.rb
class Ingredient < ActiveRecord::Base
has_and_belongs_to_many :products, :join_table => :ingredients_products
end
product.rb
class Product < ActiveRecord::Base
attr_accessible ingredient_ids
has_and_belongs_to_many :ingredients, :join_table => :ingredients_products
end
migration_xxx.rb
class CreateProductsIngredients < ActiveRecord::Migration
def self.up
create_table :ingredients_products,:id => false do |t|
t.integer :product_id
t.integer :ingredient_id
t.timestamps
end
end
def self.down
drop_table :products_ingredients
end
end
products.rb
ActiveAdmin.register Product do
form do |f|
f.inputs "Details" do
f.input :product_name
f.input :brand
f.input :ingredients
end
end
...
end

Mixing has_one and has_and_belongs_to_many associations

I'm trying to build a database of urls(links). I have a Category model that has and belongs to many Links.
Here's the migration I ran:
class CreateLinksCategories < ActiveRecord::Migration
def self.up
create_table :links_categories, :id => false do |t|
t.references :link
t.references :category
end
end
def self.down
drop_table :links_categories
end
end
Here's the Link model:
class Link < ActiveRecord::Base
validates :path, :presence => true, :format => { :with => /^(#{URI::regexp(%w(http
https))})$|^$/ }
validates :name, :presence => true
has_one :category
end
Here's the category model:
class Category < ActiveRecord::Base
has_and_belongs_to_many :links
end
And here's the error the console kicked back when I tried to associate the first link with the first category:
>>link = Link.first
=> #<Link id: 1, path: "http://www.yahoo.com", created_at: "2011-01-10...
>>category = Category.first
=> #<category id : 1, name: "News Site", created_at: "2011-01-11...
>>link.category << category
=> ActiveRecord::StatementInvalid: SQLite3::Exception: no such column :
categories.link_id:
Are my associations wrong or am I missing something in the database? I expected it to find the links_categories table. Any help is appreciated.
Why are you using HABTM here at all? Just put a belongs_to :category on Link, and a has_many :links on Category. Then in the db, you don't need a join table at all, just a :category_id on the links table.
But, if you do want a HABTM here, from a quick glance, the first thing I noticed is that your join table is named incorrectly -- it should be alphabetical, categories_links.
The second thing is that you can't mix has_one and has_and_belongs_to_many. HABTM means just that -- A has many of B and A belongs to many of B; this relationship implies that the opposite must also be true -- B has many of A and B belongs to many of A. If links HABTM cateogries, then categories must HABTM links.
See http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many