Ruby on Rails 3 (3.1) ActiveModel Associations (tableless nested models) - ruby-on-rails-3

How to impliment ActiveModel associations (tableless nested models)?
For example:
book has many chapters
With ActiveRecord I would create two models and assosiate them with has_many and belongs_to. But ActiveModel doesn't have such functionality. How can I implement this?

With rails versions >= 2.3.x you can use the activerecord-tableless gem. With that gem you can have associations and validations without a database.
Update
I have been added as author to the gem and I have updated the gem to support newer Rails versions. So now we can have tableless models with associations in Rails versions >= 2.3

You simply can't do it that way. It is not active record.
You can check ActiveModel documentation (and source code) at :
https://github.com/rails/rails/tree/master/activemodel
I guess you have to do it old fashion way, using an array of chapters and a reference to the book in the chapters.
Hope this helps!

You can check out this answer for another way to do it.
class Tableless < ActiveRecord::Base
def self.columns() #columns ||= []; end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
end
attr_accessor :id, :name, :value
has_many :stuff_things
has_many :things, :through => :stuff_things
end

Related

ActiveRecord find all children of child resources

I have Project has_many :locations and Locations has_many :comments, and Project has_many :plans and Plan has_many :comments. How do I select all the comments of all the commentable resources that belong to a project? I'm using ActiveAdmin and ActiveAdmin::Comment if that's relevant. What I've tried:
p = Project.first
comments = p.locations.map(&:comments).flatten + p.plans.map(&:comments).flatten
But is there an ActiveRecord or Rails way to do this? Or is there a SQL join that could do all that? Thanks!
if you make has_many location_comments through locations and the same for plans will be better. Also you can make model method like:
def all_comment
self.location_comments + self. plans_comments
end

FriendlyId suggest

I want to use FriendlyId to achieve this localhost3000/users/edu/profile but I do not know how to do it!
I have these models User and UserProfile
class User < ActiveRecord::Base
has_one :user_profile, :dependent => :destroy
extend FriendlyId
friendly_id :name, :use => :slugged
end
class UserProfile < ActiveRecord::Base
attr_accessible :user_id, :name, :surname, :nickname
belongs_to :user
end
How do I load in name of User the name of UserProfile? and
How do you update name of User when the name of UserProfile changes?
For the first I used
class User < ActiveRecord::Base
...
def name
if user_profile
"#{user_profile.name}"
end
end
But I can't make it change when I update or create a new Profile in UserProfile.
Using Ruby 1.9.3 and Rails 3.2.13.
If I understood it correctly, your problem is about sharing data between models, not about FriendlyId.
It seems delegate is your best bet here. It's a method in ActiveSupport that allows one model to expose another model's methods as their own.
class User < ActiveRecord::Base
delegate :name, :name=, :to => :user_profile
end
Reference: http://api.rubyonrails.org/classes/Module.html#method-i-delegate
The reason to delegate both :name and :name= is that the former method allows you to read from that attribute (getter), while the latter allows you to write to it (setter).
Before making these changes you'll want to run a migration to remove the name field from the users table in the database, since from now on you'll be using the data in the other model.
rails g migration remove_name_from_users name:string

Rails: FriendlyId gem not working

I was trying to install gem FriendlyId. I am following railscast: 314-pretty-urls-with-friendlyid. It seems pretty easy to install. But not working for me.
Here are the steps I did:
added gem "friendly_id", "~> 4.0.9" in Gemfile
I then ran bundle install command
Then modified my product model to this:
class Product < ActiveRecord::Base
extend FriendlyId
friendly_id :name
attr_accessible :name, :product_code, :recipe, :selling_price, :servings, letsrate_rateable "quality", "packaging", "hygiene" , "service", "price"
validates :name, :presence => true
class << self
def search(params)
if params[:search]
products = Product.published.includes(:product_sub_categories)
end
end
end
end
Still it is showing 'id':
http://localhost:3000/products/9
As per railscasts it should show product name. But it is not. I individually install gem but no effect.
Can anybody tell what I am missing?
Not sure why this is not mentioned in Guide, but try:
alias_attribute :to_param, :slug
This works because to_param method allows to customise the id part of URL. And here you are assigning that part to friendly_id generated URL.
Another solution
I am not sure if this is implemented inside friendly_id, but I did this:
class Product < ActiveRecord::Base
def self.find(id_or_slug)
case id_or_slug
when String
find_by_slug id_or_slug
else
super id_or_slug
end
end
end

undefined method `selector' for #<ActiveRecord::Relation:0xbb8710c> when using mongoid to save a record

undefined method `selector' for #<ActiveRecord::Relation:0xbb8710c>
I am getting this error while trying to execute the follwoing code:
c = Content.first
c.is_processed = true
c.save # or c.update_attributes(:is_processed => true)
My Content model looks like this:
class Content
include Mongoid::Document
field :username
field :name
filed :is_processed, :type => Boolean
belongs_to :language
has_many :translations
end
I am using Mongoid 2.4, bson_ext 1.5, Ruby 1.9.2, Rails 3.2.5
I found the mistake. My Content model had this line:
has_many :translations
I had migrated the content model from ActiveRecord to Mongoid. But, all the other tables are still in ActiveRecord. The has_many was referring to a ActiveRecord model. This caused the issue. I commented the line and now update is working fine.

Rails 3.1.rc1 and accept_nested_attributes_for

I have the following models:
class Survey < ActiveRecord::Base
set_primary_key :survey_id # I'm using external DB
belongs_to :user #UPDATED
has_many :questions, :dependent => :destroy
accept_nested_attributes_for :questions
end
class Question < ActiveRecord::Base
set_primary_key :question_id # I'm using external DB
belogns_to :survey
end
If I go to rails console and save a model:
>> params = {"title"=>"Survey 1", "questions_attributes"=>{"0"=>{"title"=>"Question 2"}}}
>> survey = User.first.surveys.build(params) #UPDATED
>> survey.questions.size
=> 2
>> survey = User.first.surveys.new(params)
>> survey.questions.size
=> 1
Rails is duplicating question resource on surveys. Maybe is it a Rails 3.1 bug? The code is similiar to railscasts episode 197.
It was fixed in this commit.
The fix is present Rails 3.1.0rc2, so if you update your Rails version in your Gemfile:
gem 'rails', '3.1.0.rc2'
And run
$ bundle update rails
It should work as expected.