1

I have an app with the following structure:

  • A mealplan includes one recipe for each day of the week.
  • A recipe has_many ingredients.
  • A grocery is one item on the user's grocery list.

I want to create a custom method so that when a button is clicked, it runs Grocery.create on each ingredient from the recipes on the mealplan.

I currently have the following mealplans#index method, so you can see how they're defined. (All of this is happening on the index view:

  def index
    @mealplans = Mealplan.where(user_id: current_user.id)
    @mealplan = Mealplan.new
    @recent = Mealplan.where(user_id: current_user.id).where("created_at > ?", Time.now.beginning_of_week).order("week_starting").last
    @recipes = Recipe.where(user_id: current_user.id)
    @monday = Recipe.where(id: @recent.monday)[0] if @recent.present?
    @tuesday = Recipe.where(id: @recent.tuesday)[0] if @recent.present?
    @wednesday = Recipe.where(id: @recent.wednesday)[0] if @recent.present?
    @thursday = Recipe.where(id: @recent.thursday)[0] if @recent.present?
    @friday = Recipe.where(id: @recent.friday)[0] if @recent.present?
    @saturday = Recipe.where(id: @recent.saturday)[0] if @recent.present?
    @sunday = Recipe.where(id: @recent.sunday)[0] if @recent.present?
  end

I also have a dummy mealplans#add_to_list method set up in the controller, but I feel like doing it this way violates the "skinny controllers, fat models" principle of rails.

Can anyone clue me in to the "railsiest" way to accomplish this task, according to best practices?

1 Answer 1

1

Check gem "nested_form" gem for creating multiple records.

For better implementation create scope under Mealplan model.

class Mealplan < ActiveRecord::Base
   scope :recent, ->(uid) { where(user_id: uid).where("created_at > ?", Time.now.beginning_of_week).order("week_starting").last}

   # find the day name of recent Mealplan
   def recent_day_name
     created_at.strftime("%A")
   end
end

In controller you can use this scope like this:

def index
  @mealplan = Mealplan.new
  @recent = Mealplan.recent(current_user.id)
  if @recent
    recent_day = @recent.recent_day_name
    @day = Recipe.find(id: @recent.send(recent_day))
  end
end

There is no needs to create @mealplans and @recipes instance variable on controller site:

@mealplans = Mealplan.where(user_id: current_user.id)
@recipes = Recipe.where(user_id: current_user.id)

You can get the mealplans and recipes details from current_user object.

Sign up to request clarification or add additional context in comments.

3 Comments

This scope gives me errors. It seems to have an issue with the |uid| bit, saying syntax error, unexpected '|'
Try this. scope :recent, ->(uid) { where(user_id: uid).where("created_at > ?", Time.now.beginning_of_week).order("week_starting").last }
Beautiful! That makes it much DRYer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.