Composite primary keys in ruby on rails - ruby-on-rails

I am trying to use http://compositekeys.rubyforge.org/ in order to have composite primary keys in my activerecord models.
I already added gem 'composite_primary_keys', '=3.1.0' to my Gemfile.
Now I am trying to setup my first modelclass as follows.
class StringProperty < ActiveRecord::Base
self.primary_keys :entity_id, :property_id
set_table_name "problem.string_property"
attr_accessible :entity_id, :property_id, :value
end
But all I get is:
What am I doing wrong? :(

The following will work I think.
require 'composite_primary_keys'
class StringProperty < ActiveRecord::Base
self.primary_keys = :entity_id, :property_id
set_table_name "problem.string_property"
attr_accessible :entity_id, :property_id, :value
end

If it is only for unique constraint purposes use:
class Field < ActiveRecord::Base
validates :input, uniqueness: { scope: :user_id,
message: "one input per user" }
end
source: http://guides.rubyonrails.org/active_record_validations.html

Related

Rails 4.2 How to eager load/preload associated objects with dynamic condition for them

I develop engine for Ruby on Rails project. Here you can see how I solve the problem of eager loading associated objects with dynamic condition:
My models:
#version.rb
class Version < ActiveRecord::Base
class <<self
attr_accessor :type
attr_accessor :id
end
validates :name, :description, presence: true
belongs_to :package
has_many :clustervers,:dependent => :destroy
has_many :accesses,:dependent => :destroy
has_many :user_accesses,-> { where( "who_type= ? AND who_id=?",Version.type,Version.id) }, class_name: "Access"
end
#Access.rb
class Access < ActiveRecord::Base
enum status: [:request,:allowed,:denied]
validates :version_id, :user_id,presence: true
validates_uniqueness_of :user_id, :scope => [:version_id]
belongs_to :version
belongs_to :user
belongs_to :who, :polymorphic => true
end
Controller:
def show
Version.type="User"
Version.id=2
#package = Package.find(params[:id])
#versions = Version.page(params[:page]).per(2).includes({clustervers: :core_cluster},:user_accesses)
.where(package_id:params[:id])
end
View:
for version in #versions
tr
td #{version.name}
td #{version.description}
td #{version.r_up}
td #{version.r_down}
-if version.user_accesses.take
p show attributes
-else
p no access
td
Are there more convenient methods to do this? Is it possible to do this using raw SQL statments?
I need something to generate SQL condition like this:
LEFT OUTER JOIN ... ON a.id=b.id and CONDITION

multi-tenant and use of ruby delegate vs NoSQL for tenant context

I have a multi-tenant app (rails backend) and I need to mix a tenant-agnostic pre-populated list of items with tenant specific attributes.
Was wondering if I anyone has used delegate to get this done and had ok performance vs. venturing out of Postgres into MongoDB
example models:
Class EquipmentList < ActiveRecord::Base
attr_accessible :name, :category_id
has_one :tenant_equipment_list
delegate :alt_name, to: tenant_equipment_list
end
Class TenantEquipmentList < ActiveRecord::Base
attr_accessible :alt_name, :group, :sku, :est_price, :equipment_list_id
belongs_to :equipment_list
default_scope { where(tenant_id: Tenant.current_id) }
end
I've run this successfully on a low traffic site. The rails back end handles this pretty well in outputting to json.
Realized its better to use the tenant version as the foreign key and delegate master attributes to tenant. Looks something like this:
Class EquipmentList < ActiveRecord::Base
attr_accessible :name, :category_id
has_one :tenant_equipment_list
end
Class TenantEquipmentList < ActiveRecord::Base
attr_accessible :alt_name, :group, :sku, :est_price, :equipment_list_id
belongs_to :equipment_list
delegate :name, to: tenant_equipment_list #prefix: true if you want
default_scope { where(tenant_id: Tenant.current_id) }
end

Association Clarification Rails

This is probably so simple its stupid, but I'm having a brainfreeze moment and am just staring at the screen now going nowhere.
I have two models a member and a membership, each member can have one type of membership from a selection of many.
class Member < ActiveRecord::Base
attr_accessible :forename, :middlename, :surname, :house_no, :house_name, :street, :town, :postcode, :home_tel, :mobile_tel, :work_tel, :email
end
class Membership < ActiveRecord::Base
attr_accessible :membership_type
end
My membership model will have a few records pre populated so that a member can choose which type of membership they would like, ie Peak, Off Peak, Student
Am i correct in thinking that the member model will look like this
class Member < ActiveRecord::Base
**has_one :membership**(added this)
**accepts_nested_attributes_for :membership**
attr_accessible **:membership_attributes(Added This)**, :forename, :middlename, :surname, :house_no, :house_name, :street, :town, :postcode, :home_tel, :mobile_tel, :work_tel, :email
end
So i create a migration and add the membership_id column to the member model as the foreign key?
My Membership Model can look like this
class Membership < ActiveRecord::Base
**belongs_to :member** (Added This)
attr_accessible :membership_type
end
am i looking at this correctly here?
Thanks
So i create a migration and add the membership_id column as the
foreign key?
I think that in your migration you have to add a member_id column to the memberships table, as the foreign key.
(Active Record Associations has one)

Single Table Inheritance rails has_many

I have a model called Course which needs to be associated with exams and assignments. I want to able to write code like this:
>>c = Course.new
>>assignment1 = c.assignments << Assignment.new
>>exam1 = c.exams << Exam.new
c.assessments should now include both exam1 and assignment1
How I think this should be accomplished (using single table inheritance from the Assessment model):
class Course < ActiveRecord::Base
has_many :assessments
attr_accessible :title, :name, :startDate, :endDate, :color
end
class Assessment < ActiveRecord::Base
belongs_to :course
attr_accessible :end_at, :name, :start_at, :type, :weight
end
class Assignment < Assessment
end
class Exam < Assessment
end
I've tried my best to find out how to do this but i cant seem to figure it out. Any help would be appreciated.
Course has only assesments associations so you should be able to write code like this:
c = Course.new
c.assesments << Assignment.new
c.assesments << Exam.new
Also make sure that assesments table has type column with datatype string.

Virtual attributes and mass-assignment

developers! I can't understand next situation
For Example I have model
class Pg::City < ActiveRecord::Base
belongs_to :country
#virtual accessors
attr_accessor :population
#attr_accessible :city, :isdisabled, :country_id
end
I can use code like this:
c = Pg::City.new({:population=>1000})
puts c.population
1000
But if I uncomment attr_accessible code above throw warning
WARNING: Can't mass-assign protected attributes: population
How can I use virtual attributes for mass-assigmnment together with model attributes?
Thanks!
Using attr_accessor to add a variable does not automatically add it to attr_accessible. If you are going to use attr_accessible, then you will need to add :population to the list:
attr_accessor :population
attr_accessible :city, :isdisabled, :country_id, :population

Resources