In our Rails 4 app, there are four models:
class User < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :calendars, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
Here are the corresponding migrations:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :total_calendar_count
t.integer :owned_calendar_count
t.timestamps null: false
end
end
end
class CreateAdministrations < ActiveRecord::Migration
def change
create_table :administrations do |t|
t.references :user, index: true, foreign_key: true
t.references :calendar, index: true, foreign_key: true
t.string :role
t.timestamps null: false
end
end
end
class CreateCalendars < ActiveRecord::Migration
def change
create_table :calendars do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.references :calendar, index: true, foreign_key: true
t.date :date
t.time :time
t.string :focus
t.string :format
t.string :blog_title
t.text :long_copy
t.text :short_copy
t.string :link
t.string :hashtag
t.string :media
t.float :promotion
t.string :target
t.integer :approval
t.text :comment
t.timestamps null: false
end
end
end
We have the following form to create posts:
<h2>Create a new post</h2>
<%= form_for(@post) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<tr>
<td class="field"><%= f.date_field :date, placeholder: "When do you want to publish this post?" %></td>
<td class="field"><%= f.time_field :time, placeholder: "What time do you want to publish this post?" %></td>
<td class="field"><%= f.text_field :focus, placeholder: "What is this post about?" %></td>
<td class="field"><%= f.text_field :format, placeholder: "What type of post is this?" %></td>
<td class="field"><%= f.text_field :blog_title, placeholder: "If this post is about a blog post, what is the title of the blog post?" %></td>
<td class="field"><%= f.text_area :long_copy, placeholder: "What is the copy of the post?" %></td>
<td class="field"><%= f.text_area :short_copy, placeholder: "What is the short copy of the post (to be used on Twitter for instance)?" %></td>
<td class="field"><%= f.url_field :link, placeholder: "Which link to you want to embed in this post?" %></td>
<td class="field"><%= f.text_field :hashtag, placeholder: "Which hashtag(s) do you want to you in this post?" %></td>
<td class="field"><%= f.text_field :media, placeholder: "Which media file (image, video) do you want to include in this post?" %></td>
<td class="field"><%= f.number_field :promotion, placeholder: "What advertising budget should be allocated to this post?" %></td>
<td class="field"><%= f.text_field :target, placeholder: "Who do you want to target with this post?" %></td>
<td class="field"><%= f.select(:approval, %w[Approved Needs edits To be deleted], {prompt: 'How does this post look?'}) %></td>
<td class="field"><%= f.text_area :comment, placeholder: "Any comment?" %></td>
<td><%= f.submit "Create", class: "btn btn-primary" %></td>
</tr>
<% end %>
This form is embedded into the Calendars#Show
view, so that as soon as a post is created, it appears in the corresponding calendar.
EDIT 2: And here is ou PostsController
:
class PostsController < ApplicationController
def create
@post = Post.create!
if @post.save
redirect_to root_url
else
render root_url
end
end
end
Currently, whenever we submit the form, a post is actually created (we checked through the console).
EDIT: Actually, the new @post is created and saved to the database but all values are set to nil
. It seems we also have a problem with the saving of data from the form and into the database.
However, it does not appear in the corresponding calendar.
We believe this is due to the fact that, when a post is created, the calendar_id of the active calendar (the one in which the form is embedded in) is not added to the new post instance.
However, we don't know how to implement it:
active_calendar
method and then use it to automatically assign the active_calendar
id
of the active calendar to the newly created @post
?id
as a variable, either in the post controller or the post model, so that we can add it when a new @post
is created?id
in the newly created @post
through a hidden field in the form?We kind of hit a wall here and are not sure of what we are doing wrong.
Any idea of how to fix this?
UPDATE: as suggested by @Fire-Dragon-DoL in the comments of his answer, we are going to use a hidden field.
Would the following code work?
<td type="hidden" value="#{@calendar.id}"><% f.number_field :calendar_id %></td>
I'm not sure how or where is stored your "active calendar" information, you definitely need it. Make it a field for User
, it's a good option.
Then I would create an application controller method like
def active_calendar
# Assuming you have a method to return current logged in user
current_user.try(:active_calendar)
end
Then when creating post you can easily perform the following
attrs = post_params.merge(calendar: active_calendar)
@post = Post.new(attrs)
# Or whatever logic you want
@post.save
Use the hidden field only if user is allowed to specify different calendars than the active one, otherwise it might just be a security hole
Notice that the code I wrote is also nil-proof