Ichki shakllar yordami - Mavjud mahsulotlarni yangi e'longa qanday qo'shish mumkin?

Mening modellarim to'g'ri belgilangan ko'rinadi, chunki men konsol orqali E'longa shuncha mahsulot qo'sha olaman.

MODELLAR

class Product < ActiveRecord::Base
  has_many :announcement_products
  has_many :announcements, :through => :announcement_products

  accepts_nested_attributes_for :announcements#, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

class Announcement < ActiveRecord::Base
  has_many :announcement_products
  has_many :products, :through => :announcement_products

  accepts_nested_attributes_for :products#, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

class AnnouncementProduct < ActiveRecord::Base
  belongs_to :announcement
  belongs_to :product
end

CONSOLE

a = Announcement.new()
a.products << Product.first
a.products << Product.last
a.name = 'foo'
a.description = 'bar'
a.save!

Biroq, men e'lon yaratmoqchiman va shakldagi tanlash qutisi orqali mahsulotni qo'shmoqchiman va men xatoga duch kelaman:

undefined method `product_id' for #<Announcement:0x00000103c1d7d0>

Men harakat qilib ko'rdim:

FORMASI

<% form_for([:admin, @announcement], :html => { :multipart => true }) do |f| %>

  <% if @announcement.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@announcement.errors.count, "error") %> prohibited this announcement from being saved:</h2>

      <ul>
      <% @announcement.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <ul>

    <li class="clearfix">
      <%= f.label :attachment, 'Announcement image' %>

      <div class="file_field">
        <button><!-- this is skinnable --></button>
        <%= f.file_field :attachment %>
      </div>
      <p id="file_name"><%= @announcement.attachment.blank? ? '' : File.basename(@announcement.attachment.url) %></p>

      <% unless @announcement.attachment.blank? %>
        <%= image_tag @announcement.attachment.url, :class => 'attachment_image' %>
      <% end %>
    </li>

    <li class="clearfix">
      <%= f.label :name %>
      <%= f.text_field :name %>
    </li>

    <li class="clearfix mark_it_up">
      <%= f.label :description %>
      <%= f.text_area :description %>
    </li>

    <li class="clearfix">
      <%= f.label :product_id %>
      <%= f.collection_select :product_id, Product.all, :id, :name, { :prompt => 'Select a product' } %>
      <span><%= link_to 'add', new_admin_product_path %></span>
    </li>
 ....

Shakl orqali yangi e'lon yozuviga 2 ta mahsulotni qo'shishga harakat qilyapman. Men nima noto'g'ri qilayotganimni bilmayman.


person Christian Fazzini    schedule 10.05.2011    source manba
comment
OOC - nega announcement_products ni aynan shu tarzda sozlash kerak? nega has_and_belongs-to_many dan foydalanmasligingiz kerak - bu siz uchun qo'shilish jadvalini saqlab qoladi?   -  person Taryn East    schedule 10.05.2011
comment
Chunki men m:m jadvalida ko'proq ish qilishim kerak   -  person Christian Fazzini    schedule 11.05.2011
comment
OK, shuning uchun sizga qo'shilish jadvali o'rniga haqiqiy sinf kerak kabi ko'rinadi. Masalan, Aloqa (mahsulot e'lonlari kabi). Keyin Mahsulot bor_ko'p :aloqa, lekin eng muhimi, Aloqada ko'p_mahsulot bor; has_many :announcements va keyin Mahsulot has_many :announcements :through =› :communications Keyin Rails bilan ishlash uchun standart narsa bor.   -  person Taryn East    schedule 15.05.2011


Javoblar (1)


Hozirgacha men buni o'ylab topdim. Mening formada:

<% form_for([:admin, @announcement], :html => { :multipart => true }) do |f| %>

  <% if @announcement.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@announcement.errors.count, "error") %> prohibited this announcement from being saved:</h2>

      <ul>
      <% @announcement.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <ul>

    <li class="clearfix">
      <%= f.label :attachment, 'Announcement image' %>

      <div class="file_field">
        <button><!-- this is skinnable --></button>
        <%= f.file_field :attachment %>
      </div>
      <p id="file_name"><%= @announcement.attachment.blank? ? '' : File.basename(@announcement.attachment.url) %></p>

      <% unless @announcement.attachment.blank? %>
        <%= image_tag @announcement.attachment.url, :class => 'attachment_image' %>
      <% end %>
    </li>

    <li class="clearfix">
      <%= f.label :name %>
      <%= f.text_field :name %>
    </li>

    <li class="clearfix mark_it_up">
      <%= f.label :description %>
      <%= f.text_area :description %>
    </li>

    <li class="clearfix">
      <%= select_tag 'products[]', options_from_collection_for_select(Product.all, 'id', 'name'), :id => nil, :class => 'products' %>
      <%= select_tag 'products[]', options_from_collection_for_select(Product.all, 'id', 'name'), :id => nil, :class => 'products' %>
    </li>
 ....

Keyin, mening kontrolderimda def create usuli:

  def create
    @announcement = Announcement.new(params[:announcement])

    @announcement.products << Product.find_all_by_id(params[:products])

    respond_to do |format|
      if @announcement.save
         ...
      end
    ....

Bu toza yechimmi? Yoki buni qilishning yaxshiroq yo'li bormi?

person Christian Fazzini    schedule 11.05.2011