Использование нескольких классов в форме для Rails - PullRequest
0 голосов
/ 22 февраля 2012

Я пытаюсь создать форму для следующих полей. Однако некоторые поля соответствуют одной модели, классу RecipeIngredient (модель), тогда как нижние поля соответствуют классу Recipe (модель).

  <%= form_for(:recipe_and_ingredients, :url => {:action => 'create'}) do |f| %>

<!-- RecipeIngredient classs -->
<table>
<tr>
 <td>4</td>
 <td><%= f.text_field(:quantity) %></td>
 <td><%= f.text_field(:weight) %></td>
 <td><%= f.text_field(:units) %></td>
</tr>
</table> 


<!-- Recipe class -->
<table summary="Recipe form fields">
  <tr>
    <th>Recipe Name</th>
    <td><%= f.text_field(:recipe_name) %></td>
    <th>Total Grams</th>
    <td><%= f.text_field(:total_grams) %></td>
  </tr>
</table>

<div class="form-buttons">
  <%= submit_tag("Create Recipe") %>
</div>

<% end %>

Однако в моем контроллере:

 # Instantiate a new object using form parameters
  @recipe = Recipe.new(params[:recipe_and_ingredients])
  @ingredient = RecipeIngredient.new(params[:recipe_and_ingredients])

Я получаю эту ошибку при отправке формы

  unknown attribute: quantity

Я знаю, что это потому, что модель рецепта / класс / таблица / что-либо не имеет количественного столбца; это столбец в RecipeIngredient (который должен быть таблицей соединения между Recipe и некоторой другой таблицей, если это уместно). Однако когда я отправляю параметры, как я различаю в коде, какие параметры принадлежат к какому классу?

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Это можно решить двумя способами.

Первый - использование делегирования ActiveRecord для помещения атрибута дочерней модели в родительскую модель.Вы можете увидеть документацию о том, как это сделать, здесь: http://api.rubyonrails.org/classes/Module.html#method-i-delegate

Во-вторых, вы можете использовать вложенные формы, чтобы часть этой формы принадлежала другому объекту модели.С документацией по этому вопросу можно ознакомиться здесь: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

1 голос
/ 22 февраля 2012

использование В модели: accepts_nested_attributes_for
В контроллере: ничего
В маршрутах: ничего
В представлении, в точке, где вы хотите «вложенные» поля, используйте f.fields_for :other_model do |inner|, а затем вы можете использовать inner.inner_field_name. Я думаю, что внутренняя часть будет компонентом в вашем случае, если это то, чем является RecipieIngredient, и вы переименовали его в ингредиент. Если receiveieIngredient на самом деле является более сложной таблицей соединений, переделайте при необходимости.

Подробнее на http://railscasts.com/episodes/196-nested-model-form-part-1

Я бы назвал сущности «получателями» и «ингредиентами», а затем получил бы форму для получателя с fields_for :ingredients do |i|.

Если вы хотите Ingredient has_many recipies и Recipie has_many ingredients, вы можете сделать это тоже с помощью has_many_through в обеих моделях, указывающих на модель соединения IngredientRecipie, которая принадлежит получателю и компоненту, но не влияет на форму , Эти отношения используются для извлечения данных.

Обратите внимание, что если у вас есть эти has_many, вы можете использовать simple_form, чтобы просто поддерживать отношения с флажками для отношений и никаким другим кодом для записи, кроме сохранения данных одним сохранением.

Обновление:

Recipie (model)
Recipie has_many :recipie_ingredients
Recipie has many :ingredients, :through => :recipie_ingredients

Ingredient (model)
Recipie has_many :recipie_ingredients
Recipie has many :ingredients, :through => :recipie_ingredients

RecipieIngredient (model)
belongs_to :recipies
belongs_to :ingredients
...