Ruby on Rails: create an instance that "belongs_to" another Class - ruby-on-rails-3

Well, i'm new on rails, and I has the following:
class Post < ActiveRecord::Base
belongs_to :category
...
end
and
class Category < ActiveRecord::Base
has_many :posts
...
end
I want to create a post, and select its category from a drop down with:
...
select("post", "category", Post::CATEGORIES, {:include_blank => true})
...
When I try to save, it says that category attribute doesnt exists.
How can I do it?

The post table contains only category id, so you need to assign to category_id:
select("post", "category_id", Post::CATEGORIES, :include_blank => true)

Related

has_many :condition multiple models how to use join here?

I have the following model structure:
Model Visitor
class Visitor < ActiveRecord::Base
has_many: triggers
end
Model Trigger
class Trigger < ActiveRecord::Base
belongs_to :visitor, :inverse_of => :triggers
belongs_to :event, :inverse_of => :triggers
end
Model Event
class Event < ActiveRecord::Base
has_many: triggers
end
I am trying to setup a custom association in Visitor model like so:
has_many: triggers_that_pass_some_condition ,:class_name => "Trigger",
:conditions => ["triggers.some_column >= events.some_column"]
The problem is that it doesn't work .. I am guessing I have to do some kind of join to compare columns of two separate models (that are associated with each other)
I have tried
triggers.some_column >= triggers.event.some_column
That does not work either. Anyone has any suggestions? thanks!
Try the following code..
class Trigger < ActiveRecord::Base
belongs_to :event
belongs_to :visitor
end
# Visitors.rb
has_many :triggers_with_condition, -> { includes(:event).where(some_trigger_column >= event.some_event_column)}, class_name: "Trigger"
Make sure you first add the correct association between Visitor and Trigger in your model setup. From there, you can add a custom association as follows:
class Visitor < ActiveRecord::Base
has_many :approved_triggers, -> { includes(:events).where("events.something = ?", true).references(:events) }, class_name: 'Trigger', inverse_of: :visitor
end
class Trigger < ActiveRecord::Base
belongs_to :visitor, inverse_of :triggers
end
Right now your Trigger class holds no association to a Visitor.
Thanks to the clue from Darpa, I eventually settled on this:
has_many :custom_trigger, {:class_name => "Trigger", :include => :event,
:conditions => ["triggers.some_column >= events.another_column"]}

Uniqueness validation with a has_many relationship

My model structure is as follows:
class Client < ActiveRecord::Base
has_many :charts
end
class Chart < ActiveRecord::Base
belongs_to :client
has_many :chart_data
end
class ChartDatum < ActiveRecord::Base
belongs_to :chart
end
ChartDatum has an attribute called 'name' which needs to be unique for each client.
I tried using "validates_uniqueness_of :name, :scope => [:chart_id]" but this helped me getting a unique key for a particular chart but not for all charts for a particular client. I am looking for something like "validates_uniqueness_of :name, :scope => [:client_id]" but obviously with the current structure it will not work out.
Could someone please help me?
Since you need unique name for chart_data for each client, you can try writing a custom validation for name something like this :
class ChartDatum < ActiveRecord::Base
belongs_to :chart
validates :name, :uniqueness => true, unless => :unique_for_client?
def unique_for_client?
client = self.chart.client
client.charts.chart_data.pluck(:name).include?(self.name)
end
end

has_many :through causes error: HasManyThroughSourceAssociationMacroError

I need to assign students (users) to classes (studentclasses)
I have a simple many-to-many relationship using 3 tables:
studentclasses (lesson details)
users (user... student info)
studentclass_users (Join table containing user_id and studentclass_id)
I'm using has_many :through and my models look like the following:
studentclass.rb
class Studentclass < ActiveRecord::Base
has_many :studentclass_users
has_many :users, :through => :studentclass_users
end
user.rb
class User < ActiveRecord::Base
...more here...
has_many :studentclass_users
has_many :studentclasses, :through => :studentclass_users
end
studentclass_users.rb
class StudentclassUsers < ActiveRecord::Base
belongs_to :studentclass
belongs_to :user
end
For testing purposes, I'm just using a hidden field in my studentclass new view partial to tack on a user id when creating the class and it is as follows:
_new.html.erb
<%= hidden_field_tag "studentclass[user_ids][]", 29%>
And in my studentclass controller:
studentclasses_controller.rb
def new
#studentclass = Studentclass.new
end
def create
#studentclass = Studentclass.new(params[:studentclass])
#studentclass.save!
end
My params comes back:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"MjBTf4rtcyo8inADrSxPZB3vLOKtlZRVFlQJJzfCqWs=", "studentclass"=>{"class_title"=>"hjhkj", "user_ids"=>["29"]}, "commit"=>"Save"}
which seems fine but I get the following error:
NameError (uninitialized constant ActiveRecord::HasManyThroughSourceAssociationMacroError):
I think this is something simple with naming maybe? Any help would be appreciated

Find and count all Profiles with object name of HABTM relationship

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") %>

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