rails model dependencies and callbacks - ruby-on-rails

I work on a restaurant rails app, where every restaurant has a classification "cheap" or "fancy", depending on the price of its menu.
I would like to refresh the classification every time a menu change, or the price of an ingredient composing the menu.
models/
# restaurants.rb
has_many :dishes
# dishes.rb
has_many :ingredients, through: :recipes
# recipes.rb
belongs_to :ingredient
belongs_to :dish
# quantity :integer
# ingredients.rb
has_one :price
Today, I am using after_save callbacks in each model.
I am wondering if there is a more elegant way ? A rails feature / gem I can ask:
Notify me every time a change impacts a restaurant !

Related

Active Admin Querying on Association Tables Column presence and on its value

I want to active admin filters on an admin panel page based on its column presence.
The model association is as follows:
class User < ActiveRecord::Base
has_many :objects, through: :orders
has_many :orders
end
class Order < ActiveRecord::Base
belongs_to :user
belongs_to :object
end
class Object < ActiveRecord::Base
has_many :users, through: :orders
has_many :orders
end
An order has a quantity column in it.
I want to filter on index page of users in my admin pages which is integrated with active admin gem.
Ex: I want to filter as follows:
users with object quantity greater than 5.
I should check for association record presence and check for the quantities greater than 5 and only show that users.
I also need the negation filters as well.
I want to check for the users who don't buy an order.
I tried to use ransack:
For this, I need to add ransack search query for each object records. Is there any intuitive or any way I can achieve this functionality.

Compare data from two tables in rails and post in third

I have three models; User, Project, Skill. I have associated user & skill and skill & project. Now I want to assign a project to users based on skill, if they have the skill needed for the project they can be assigned, otherwise can't. No limit on how many users can work on one project.
I am working on rails. Need a start to the problem.
One method to get a view of available projects/users would be to add has_many :through to each using the skills table....
def User < ActiveRecord
belongs_to :skill
has_many :available_projects, through: :skill, source: :project
end
def Project < ActiveRecord
belongs_to :skill
has_many :available_users, through: :skill, source: :user
end
Then call the associations as needed...
user.available_projects
and...
project.available_users

Modeling Relationships with Four or More Models in Rails

I have these models in my Rails app:
group.rb
has_many :group_members
has_many :group_foo_types
group_member.rb
# fields
:group_id, :user_id
belongs_to:group
has_many :group_foo_types, :through=>:groups
has_one :user
has_many :foo, :through=>:user
has_many :bar, :through=>:user
group_foo_type.rb
# fields
:group_id, :foo_type_id
belongs_to :group
belongs_to :foo_type
user.rb
has_many :foo
has_many :bar
foo.rb
# fields
:user_id, :foo_type_id
belongs_to :user
belongs_to :foo_type
bar.rb
# fields
:user_id, :foo_type_id
belongs_to :user
belongs_to :foo_type
What I'm trying to do is, for a group, find the foos and bars per user taking into account the foo_type_id for the group (from group_foo_type).
However, I'm not sure if I have this modeled correctly.
From this, it seems like I can do group.group_members.user to get the users and then user.foos' and 'user.bars to get a user's foos and bars. This doesn't take into account the foo_type_id for the group though (from group_foo_type).
Can someone please help recommend an approach to accomplish what I want to do? Thank you!
As mentioned in this answer, since Rails 3.1 you can nest has_many :through associations. So to have easy access to all of a group's foos and bars, you could add the following associations:
# group.rb
has_many :users, through: :group_members
has_many :foos, through: :users
has_many :bars, through: :users
With this, group.foos would give you all of the group's foos (via group_member and user).
The association methods in rails can be used with the various finder methods, so to limit the foos by group_foo_type:
group_foos = group.foos.where(foo_type_id: group.group_foo_type_ids)
(group_foo_type_ids being another useful association method, check the Association Basics guide for more info.)
A caution: there are a lot of steps that have to go on in the background to achieve any of this stuff, even if it does get relatively easy to actually code. You may want to keep an eye on the queries that get generated (either through the console or logs) and how they perform, as they're likely to get fairly involved. It looks like you have a fairly complex set of associations there, so it may be worth looking at whether you can simplify anything there. Just something to keep in mind!

Association belongs_to :through

I know that isn't any belongs_to :through association in Rails, but how could I work around it?
User model has many Batches
Batch model has many Forecasts
I want to create an association stating that a Forecast belongs to a User. However, I understand that since a Forecast already belongs to a User, it shouldn't be necessary to store used_id inside Forecast model.
How can I create this relationship between Forecast and User through the Batch model?
EDIT
Let me better explain my problem.
I have the following models and associations:
User < ActiveRecord::Base
has_many :batches
# has_many :forecasts, through: :batches
end
Batch < ActiveRecord::Base
belongs_to :user
has_many :forecasts
end
Forecast < ActiveRecord::Base
belongs_to :batch
# belongs_to :user, through: :batch
end
The commented lines is what I want to do, but I cannot, since there is no belongs_to :through association.
The relationship is strictly what is said on the code: a User may have many batches. A batch is a set of forecasts, so a Batch may have many forecasts. Since a Batch must belong to a User, and a Forecast must belong to a Batch, then a Forecast belongs to a User.
I want to get select all Forecasts that belongs to all Batches from a User.
current_user.forecasts
The reason I want to do that, is to limit the scope of a user only to its own batches and forecasts. So on controller actions, instead of
Batch.find(params[:id])
or
Forecast.find(params[:id])
I can make
current_user.batches.find(params[:id])
or
current_user.forecasts.find(params[:id])
It is already possible to do that with Batch. Forecasts, on the other hand, doesn't belongs_to a user yet. How can I do that?
There is has_many :through in Rails. You can check out the Rails guide to see how to use it.
In your User model:
has_many :batches
has_many :forecasts, :through => :batches
In your Batches model:
belongs_to :user
belongs_to :forecasts
In your Forecasts model:
has_many :batches
has_many :users, :through => :batches
That last line is just if you want the relationship to go both ways, like a full many-to-many relationship.

Rails Multi Table Inheritance and Polymorphic Associations

I'm currently developing an application using Rails 3.2 and have run into a bit of a problem. I know this has been asked hundreds of times before but I couldn't find an answer that solved it. Here is a similar ER: http://i.stack.imgur.com/x5V0G.png
Fairly obvious what i'm trying to do. I'm hoping for the association to read like the following:
Supplier.first.theatres.first.events.first.orders
TourEvent.first.orders
Tour.first.orders
Now it would be nice to be able to define my models like so:
class Event < ActiveRecord::Base
has_many :orders
belongs_to :eventable, polymorphic: true
# id, eventable_id, eventable_type, title, date, price
end
class TourEvent < Event
belongs_to :tour
# id, tour_id, rendezvous, guide_name
end
class Tour < ActiveRecord::Base
has_many :events, class_name: 'TourEvent'
# id, name, venue, duration
end
But I understand that's reserved for "STI" rather than "MTI". Any ideas how to get my solution working without the need for complicated mixins or plugins? Or is it just not possible?
I think you can make something like this:
suppliers
has_many :events
events
belongs_to :suppliers
belongs_to :institutions
has_many :orders
# id, supplier_id, institution_id, ...
institutions
# id, type, title, ...
types: theatre, club, tour
orders
belongs_to :events
# id, event_id
Then, you can access to event orders:
Supplier.first.events.first.orders

Resources