Reputation: 606
I have read about curval, lastval and the best one, returning id, but all the examples I have seen were written in plain sql (insert ...)
However, I am using active record here in my controller. The thing is I have a New Form to add articles with the File Upload field, but I also want to add pictures, which are in other table, so since the Pictures table has a Foreign Key pointing to Articles table, I need that last ID to do the insertion in my pictures table.
Here is the method in the Articles Controller
def create
@article = current_user.articles.build(article_params)
if @article.save
flash[:success] = "Article created!"
redirect_to root_url
else
render 'articles/new'
end
Picture Model:
class Picture < ActiveRecord::Base
belongs_to :article
mount_uploader :picture, PictureUploader
end
And the Article Model has this
class Article < ActiveRecord::Base
belongs_to :user
has_many :pictures
accepts_nested_attributes_for :pictures, allow_destroy: true
plus the validations
Update:
I have read that in this case, by writing Article.id you get the id of the last inserted row in the Articles table, yet, the second part of the question still remains, how do you use that to add it to the Save command to the Pictures table.
So, how do you go about that? simply writing "returning id below the line if @article.save ? (this is the kind of problems that arise when abandoning clear sql and having to write Active Record, I am lost with it. Then it is also unclear so far how to add that returning id to the Save method in the Pictures. UPDATE 2:
I am including the strong parameters
def article_params
params.require(:article).permit(:country, :region, :town, :street, :company, :title, :content, :picture)
end
The Top of the form
<%= form_for(@article, html: { multipart: true }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
MY UPDATE:
The answer was still not correct as first there was a small bug in the fields_for in the Form which caused the picture not to be sent to the controller.
But once someone helped me with that, still there was a problem, which was that the picture simply would not get saved.
I looked in the Log and I could read: Unpermitted parameter picture. This was saying that the strong parameters private method was not correct when it came to the Pictures table. That is, this was not correct:
params.require(:article).permit(:country, :region, :town, :street, :company, :title, :content, :picture)
but the attribute picture had to be broken down in its parts like this:
def article_params
params.require(:article).permit(:country, :region, :town, :street, :company, :title, :content, pictures_attributes: [:id, :article_id, :picture])
end
And this finally solved it, but for someone who has been teaching Rails himself for two weeks, it was a challenge, despite having read most of the Guides and even the Hartl book. This was, to me, a bit advanced.
Upvotes: 0
Views: 1160
Reputation: 6438
While creating the article
, you don't need to manually assign the article_id
to the picture
object.
With all the models, associations in place and using the appropriate form helpers, you can let rails
handle that for you.
Assuming you have a title
field on the articles
tables, you could use the following form, which when submitted, will setup both article
and pictures
for that article
.
<%= form_for @article, html: { multipart: true } do |f| %>
<%= f.text_field :title %>
<%= fields_for :pictures do |ff| %>
<%= ff.file_field :picture %>
<% end %>
<% end %>
You also need to setup/build these pictures
in your new
action of the ArticlesController
as follows:
class ArticlesController < ApplicationController
def new
@article = current_user.articles.build
@article.pictures.build
end
end
And let rails
know that you want to accept picture
arguments from the article
model as follows:
class Article < ActiveRecord::Base
belongs_to :user
has_many :pictures
accepts_nested_attributes_for :pictures
end
Refer to FormHelpers#fields_for for more info.
Upvotes: 0
Reputation: 163
If you are adding pictures directly in the article form, you should build the pictures as so.
@article = current_user.articles.build(article_params)
@article.pictures.build
and in your models/article.rb
add accepts_nested_attributes_for :pictures
. so that you are able to add f.form_for :pictures do |ff|
like so. Remember to add the attributes into the strong params as well.
Upvotes: 2