Struggling with rails_admin multiple HABTM associations to same model - ruby-on-rails-3

I'm looked all over Google, the Rails_Admin dox, etc and can't find an answer.
I have a model agency:
class Agency < ActiveRecord::Base
has_and_belongs_to_many :kids
And the kids model:
class Kid < ActiveRecord::Base
has_and_belongs_to_many :agencies
attr_accessible :agency_ids
In Rails_Admin, I access the agencies with this code:
config.model Kid do
edit do
field :agencies
end
end
However, for the life of me, I can't figure out how to have an association to the same model in a different field. Something like:
config.model Kid do
edit do
field :agencies
field :agencies_previous
end
end
where agencies_previous and agencies would reference the same agencies model.

I think that what you need is something like https://github.com/benedikt/mongoid-tree where you can reference a self model, its that what you need?

Related

How to manually join two different table with different attribute name in Ruby on Rails controller

I am currently making a website that runs on Ruby on Rails. I am facing some issues while I was trying to join two tables, Rates and Locations, that I have with two different attributes name.
Rates: id rater_id rateable_id (and a few more attributes in this table)
Locations: id title body user_id (and a few more attributes in this table)
Here is the query that I am trying to do in SQL.
SELECT *
FROM rates, locations
WHERE rates.rater_id = locations.user_id AND rates.rateable_id = locations.id
I have read the official active record documents that provided by rubyonrails.org. I have tried doing these, but it does not work. Here is the code that I am trying to implant in app\controllers\users_controller.rb
#join_rating = Rate.joins(:locations).where("rates.rateable_id = locations.id AND rates.rater_id = locations.id")
#all_rating = #all_rating.where(rater_id: #user)
#count_all_rating = #all_rating.count
#join_rating, is trying to join the attributes with different names.
#all_rating, is trying to filter which location to show using the user ID
#join_rating, is trying to calculate the total numbers of locations that are rated by the user
Assume that everything is setup correctly and the only error is in the query that I am trying to do, how should I rewrite the statement so that I am able to show the locations that the user has rated using #all_rating.
Thank you!
A few points:
When in ActiveRecord you're starting a statement with the Rate class, it means the result is going to be a collection of Rate objects. So if you're trying to show locations, you should start with a Location class.
#locations_user_rated = Location.joins('INNER JOIN rates ON
rates.rateable_id = locations.id').where('rates.rater_id' => #user)
And if your ActiveRecord associations are well defined, you could simply do:
#locations_user_rated = Location.joins(:rates).where('rates.rater_id' => #user)
"Well defined" simply means you'll need to do something like the following. Note that I am not sure I understand your model relationships correctly. I assume below that every location has multiple rates, and that the reason your Rate model has the field called rateable_id instead of a location_id is because you want :rateable to be polymorphic. This means you probably also have a rateable_type field in rates table.
class Location < ActiveRecord::Base
has_many :rates, as: :rateable
end
class Rate < ActiveRecord::Base
belongs_to :rateable, polymorphic: true
end
If this polymorphism is not the case, things should actually be simpler, and I highly recommend that you follow Rails's conventions and simply name the relationship field location_id on your Rate model instead of rateable_id. Then you can do:
class Location < ActiveRecord::Base
has_many :rates
end
class Rate < ActiveRecord::Base
belongs_to :location
end
If still you are not convinced about the field name, you can customize things and do:
class Location < ActiveRecord::Base
has_many :rates, foreign_key: :rateable_id
end
class Rate < ActiveRecord::Base
belongs_to :location, foreign_key: :rateable_id
end
You can find more about how to customize associations here, and here.
I highly recommend taking advantage of ActiveRecord's has_many, belongs_to, and has_many through: functionality.
If you set up a model for each of these tables, with the correct relationships:
class User < ActiveRecord::Base
has_many :ratings, foreign_key: :rater_id
has_many :rated_locations, through: ratings, class_name: Location.name, source: :rater
end
class Rating < ActiveRecord::Base
belongs_to :rater, class_name: User.name
belongs_to :location
end
class Location < ActiveRecord::Base
has_many :ratings
end
Then to access the locaitons that a user has rated, you just call
user.rated_locations

How to implement has_many :through relationship in rails with this example

i've been searching through similar questions but i still don't get how implement this relationship. I have of course three models :
class Recetum < ActiveRecord::Base
attr_accessible :name, :desc, :duration, :prep, :photo, :topic_id
has_many :manifests
has_many :ingredients, :through => :manifests
end
class Ingredient < ActiveRecord::Base
attr_accessible :kcal, :name, :use, :unity
has_many :manifests
has_many :recetum, :through => :manifests
end
class Manifest < ActiveRecord::Base
attr_accessible :ingredient_id, :quantity, :receta_id
belongs_to :recetum
accepts_nested_attributes_for :ingredient
belongs_to :ingredient
end
Recetum would be a recipe (typo when scaffolding), this recipe may have one or more ingredients (already on the db). So when i create a new Recetum, i need the new recetum to be created and one record inserted in manifest for each ingredient entered by the user.
I would need some help now with views and controllers, how do i create the form for recetum with fields for the ingredients and more important what do i have to modify recetum controller.
Any suggestions or help would be very much appreciated as this part is crucial for my project, thanks in advance.
You have a couple options, and mainly they depend on what you want to do in your view. Do you want to display a set number of max_ingredients or do you want it to be completely dynamic? The dynamic case looks better for the user for sure, but it does make for some more complicated code.
Here is a good RailsCast which explains how to do it dynamically via JavaScript:
http://railscasts.com/episodes/74-complex-forms-part-2
Unfortunately, not everyone runs with JavaScript enabled so you may want to consider doing it the static way.
Firstly, I don't think you need accepts_nested_attributes_for in your Manifest model. However, I do think you need it in your Recetum model. If you're going the static route, you'll probably want to set a reject_if option too.
accepts_nested_attributes_for :manifests, reject_if: :all_blank
Once you do this, you'll need to add manifests_attributes to your attr_accessible.
With the static route, you'll need to prebuild some of the manifests. In your new controller you'll want something like this:
max_ingredients.times do
#recetum.manifests.build
end
In your edit and the error paths of your create and update, you may want:
(max_ingredients - #recetum.manifests.count).times do
#recetum.manifests.build
end
Finally, your view will need some way to set the ingredient. I'll assume a select box for now.
f.fields_for :manifests do |mf|
mf.label :ingredient_id, "Ingredient"
mf.collection_select :ingredient_id, Ingredient.all, :id, :name
You'll want to add some sort of formatting through a list or table probably.
Hopefully, that's enough to get you started.

Multiple Table Class Inheritence for ruby on rails

I need to set up a multiple class inheritance model here for the following models. Basically I'm building an extensible contacts directory. From a base class Contact I intend to derive other classes i.e something on the lines of :
class Contact
# the super class
attr_accessible :name, :about
end
class Person < Contact
attr_accessible :first_name, last_name, :description, :works_for_company_id
end
class Company < Contact
attr_accessible :company_name, :location, :services
end
Each model corresponds to a different table - I'm assuming that there would be a has_one belongs_to relation ship between teh parent and the child classes however I was wondering if theres a gem that can ease it a bit. Or if I have to do it myself how would I actually accomplish it.
For example contact.name is actually person.first_name+' '+person.last_name for a person or company.company_name for the company. How do I structure my database and associations to get this right?

Rails Form with has_many through - Which model to choose?

I have the following models:
Student has_many :subjects, :through => :classes
Subject has_many :students, :through => :classes
Class belongs_to :subject
belongs_to :student
The model class has an extra attribute (among the foreign keys to subject and students table) called level.
Basically I want to be able to have a form that will let the student to choose a subject and relate that subject to its record. So, I have this:
ClassesController < ApplicationController
def new
#list_of_subjects = Subject.all
# What should I do here?
end
My question is: How should I create the object for the form? From which model it should be, subject, student or class? I want to be able to create a record in the class table that would relate the student and the subject that the student has chosen, but I don't know if I am doing it wrong.
Thanks
I didn't think you could create a model called Class since it's a keyword, but that's neither here nor there...
First I think your controller and view should be using Student since it's the student that's selecting these things. Next, I think what you want to do is to add accepts_nested_attributes_for :class in your Student model which allows you to create an instance of the Class connector model from Student.
What you're trying to do sounds a little like something I tried to do. I have my full code there.
Using nested attributes to easily select associations in a form
I later refined it a bit in this question too to make the code less hideous:
Rails: How do I prepend or insert an association with build?
I know it's late, but I hope that helps.

Filter based on model attribute has_many relationship through, rails 3?

I have a simple question, but can't seem to find any solution, though I have found things that are similar, but just not exactly what I am looking for.
I have an application where a User has many Assets through the class UserAsset. I want to be able to do current_user.user_assets , but I only want to return records that have an Asset with a specified field value of "active".
This post is similar but I need to use the main model not the join model as a filter.
class UserAsset < ActiveRecord::Base
belongs_to :asset
belongs_to :user
end
class Asset < ActiveRecord::Base
has_many :user_assets
has_many :users, :through => :user_assets
end
class User < ActiveRecord::Base
has_many :user_assets
has_many :assets, :through => :user_assets
end
I tried setting the default scope on Asset, and also some conditions on the has many (user_assets) relationship, but rails is failing to consider the join on the Assets table. ie Unknown column 'asset.live' in 'where clause'. Trying to achieve the following:
#active_user_assets = current_user.user_assets #only where assets.active = true
So how do I use conditions or scopes to achieve this? I need the user_asset object because it contains info about the relationship that is relevant.
Thanks in advance!
You want current_user.assets, then your scopes should work.
Oh, but you want the user_assets. Hmm. I think you need the :include clause to find() but where to put it, I can't be arsed to think of right now.
Perhaps
current_user.user_assets.find(:all, :include => :assets).where('asset.live=?', true)
(I'm not on Rails 3 yet, so that's going to be mangled)
Are you using :through when you really want a HABTM?