开发者

Rails model/form layout question

开发者 https://www.devze.com 2023-03-07 18:14 出处:网络
I\'m making a recipe-manager (who isn\'t as their first app?) in Rails, and here is my layout: Ingredient belongs to Recipe

I'm making a recipe-manager (who isn't as their first app?) in Rails, and here is my layout:

Ingredient belongs to Recipe
Recipe has many Ingredients

What is the best way to make a form that reflects this relationship? I was thinking an input that, when one is filled, creates another, so there is always 'one more' at the end of the form for ingredients.

Once I have the UI made, what would the structure of the model and controller look like? Right now I have the scaffolded controller create method:

  def create
    @recipe = Recipe.new(params[:recipe])

    respond_to do |format|
      if @recipe.save
        format.html { redirect_to(recipes_path, :notice => 'You made a new recipe!') }
        format.xml  { render :xml => @recipe, :status => :created, :location => @recipe }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @recipe.errors, :status => :unprocessable_entity }
      end
    end开发者_JAVA技巧
  end

Should the params[:recipe] just be a more deeply nested object/hash/dictionary, that contains an array of ingredients or something?

Thanks for any guidance here.


You should use accepts_nested_attributes here.

Some links:

API:
http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for
Screencasts:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2

So your model will look like this

class Recipie  < ActiveRecord::Base 
  has_many :ingredients
  accepts_nested_attributes_for :ingridients, :allow_destroy => true
end

Views:

<%= form_for @recipe do |f| %>
  ... # reciepe fields
  <%= f.fields_for :ingridients do |i| %>
    ... # your ingridients forms
  <% end %>
  ...
<% end %>

And controller

def create
  @recipe = Recipe.new(params[:recipe])
  @recipe.save # some save processing
end


Just add ingredients by comma delimited.

This can be a text_field_tag because you will need to parse it and save each word spaced by a comma with a before save.

class Recipie  < ActiveRecord::Base 

    has_many :ingredients

    before_save :add_ingredients 

    attr_accessor :ingredients_to_parse #this will be the text_field_tag

    def add_ingredients
        #create an array of ingredients from #ingredients_to_parse
        #then loop through that array i.e. you have your ingredients_array   
        ingredients_array.each do 
            Ingredient.create(:recipe => self, :other_params => 'stuff')
        end
        #there are a lot of ways, I just used create to show you how to add it
    end
end

So then in your form just have that text_field_tag

<%= form_for(@recipe) do |f| %>
    <% f.text_field :name %>
    <% text_field_tag :ingredients_to_parse %>
    <%= f.submit %>
<% end %>

Then you can add Javascript so that each time a comma is added in that text_field_tag you can just use some js to to so fancy stuff.

This way it will work when servers are slow, js is not working well, etc. It's always a good idea to get the HTML version going first too.

Good luck, let me know if you have questions/problems.

0

精彩评论

暂无评论...
验证码 换一张
取 消