Hello, I teach rails, I decided to write an account store for myself. There are two models: Account, Image. Ideally, what would be used when creating an account through form_for I could register a list of images for an account that are then displayed on the page (link has_many , belogs_to ). But for now, I’d need to specify one image for my account when creating it.

accounts_controller:

  def create render json: params @account = Account.new(require_params) if @account.save redirect_to @account else render :new end end 

_form

 <%= form_for(@account) do |f| %> <%= f.label :title %><br> <%= f.text_field :title %><br> <%= f.label :desc, 'descriprion'%><br> <%= f.text_area :desc %><br> <%= f.label :price %><br> <%= f.text_field :price %><br> <%= f.label :data %><br> <%= f.text_area :data %><br> <%= fields_for @account.images.build do |g| %> <%= g.label :link %> <%= g.text_field :link %> <%end%> <%= f.submit %> <%end%> 

schema

  create_table "accounts", force: :cascade do |t| t.string "title" t.text "desc" t.text "data" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "price" end create_table "images", force: :cascade do |t| t.string "link" t.integer "account_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "images", ["account_id"], name: "index_images_on_account_id" 
  • Show Model Account - cheops 2:41 pm
  • @cheops class Account < ActiveRecord::Base validates :title, presence: true, length: {minimum: 10} validates :desc, presence: true, length: {minimum: 10} validates :data, presence: true, length: {minimum: 4} #validates :price, presence: true has_many :images end - Escobar

3 answers 3

If you decide to use accepts_nested_attributes_for (and tweak the strong parameters so that the nested fields are allowed), then you will have to twist the form, fields_for your fields_for now defines the fields in the root and not in the other model, the fields of these two models are not "one inside the other " , and next .

 <%= f.text_area :data %><br> <%= fields_for @account.images.build do |g| %> <%= g.label :link %> <%= g.text_field :link %> <% end %> 

See the discontinuity? f.text_area is an @account field. And fields_for does not rely on f and therefore the fields from the g builder will not fall into params[:account] defined by it, but will lie side by side, into params[:image] .

It should be like this:

 <%= f.text_area :data %><br> <%= f.fields_for :images, @account.images.build do |g| %> <%= g.label :link %> <%= g.text_field :link %> <% end %> 

This is only one of the options for determining such a form.

Bundle of examples in the Rails documentation for the fields_for method , Nested Attributes Examples section.

  • Thank you, very informative. - Escobar

Add accepts_nested_attributes_for to the Account model for association images

 class Account < ActiveRecord::Base validates :title, presence: true, length: {minimum: 10} validates :desc, presence: true, length: {minimum: 10} validates :data, presence: true, length: {minimum: 4} #validates :price, presence: true has_many :images accepts_nested_attributes_for :images, allow_destroy: true end 

In the require_params in the controller should add permission to edit images

 def require_params params.require(:account).permit( :title, :desc, :data, :price, images: [:id, :link, :account_id, :_destroy] ) end 
  • It did not help, the account saves and the image does not. Here is create params: {"utf8":"✓","auth..":"8jH0...==","account":{"title":"myAccountTitle","desc":"myAccountDesc","price":"4544","data":"lolol@ruggok.com:54GRg4tdgddd"}, "image":{"link":"http://wot-game.com//w.jpg"},"commit":"Create Account","controller":"accounts","action":"create"} Through the console, I created an account like this: u = Account.new title:" myAccountTitle ", desc:" myAccountDesc ", data: "lolol@r.com: 54GRg", price: 4544 u.save u.images.create link: " wot-game.c ..." - Escobar
  • @VolodymyrLapan In account.images.errors.full_messages is there anything interesting? - cheops
  • There are no errors, it just saves the account without the image probably with require_params something is wrong. - Escobar

Solved the problem by creating a separate variable for image. def new @account = Account.new @image = @account.images.new end def create # render json: params @account = Account.new(require_params) if @account.save @image = @account.images.create(image_params) redirect_to @account else render :new end end def require_params params.require(:account).permit( :title, :desc, :data, :price #image: [:id, :link, :account_id, :_destroy]) end def image_params params.require(:image).permit(:link, :account_id) end If anyone has the best solutions to this problem, please write in the comments! Since I'm just starting out and doing as I can and not as correctly.