我正在尝试在Rails 4中创建一个应用程序。
我有一个名为finalize的模型,它有两个属性。一个是名为:draft的布尔值,另一个是名为:finalised_at的日期时间。 Finalize属于我的项目模型。项目已经完成了。
这个想法是用户创建新项目,但将它们存储为草稿直到准备发布。在我的项目展示页面中,我的展示页面上有一个链接,以便在创建项目时if:draft为true,您可以单击链接将其切换为false。
当:草稿变为虚假时,我想写:发布于[插入日期:草稿变为假]。
我的目标是在我的项目页面上建立一个链接,该链接仅对创建项目的用户可见,并且只有:draft为true。链接说"敲定草稿"并且是一个将草稿属性切换为false的链接。只要草稿是假的(当点击此链接时,或者如果创建了新项目并且从未将其保存为草稿,因为草稿从创建点开始为假),则显示项目不再是草稿的日期对项目展示页面上的所有用户。
我想做的是编写一种方法,知道如何捕获用户点击链接以生成项目的日期:draft = false。目前,我使用Time.now函数完成所有工作,而不是草稿变为假的时间。
我的第一次尝试是:
在我的终结控制器中,我有:
def toggle_draft
@finalise = Finalise.find(params[:id])
@finalise.draft = false
@finalise.finalised = Time.now
@finalise.save
redirect_to project_path(Project.find(params[:projectid]))
end
在我的最终视图中,我有:
<% if @project.finalise.draft == true %>
<%= link_to 'Finalise draft', finalise_toggle_draft_path(projectid: @project.id, id: @project.finalise.id, finalise_id: @project.finalise.id), method: :patch %>
<% end %>
<% if @project.scope.finalise.draft == false %>
<div class="datasubtextq">Published on <%= @project.scope.finalise.finalised.try(:strftime, '%d %B %Y') %></div>
<% end %>
我接着在下面收到了一条建议,尽管该用户现在建议它可能没有用于此目的:
该建议涉及在我的finalises.rb中包含一个方法,如下所示,并将我的观点改为:
<% if @project.scope.finalise.draft == false %>
<div class="datasubtextq">Published on <%= @project.scope.finalise.finalised_at.try(:strftime, '%d %B %Y') %></div>
<% end %>
在finalise.rb
def set_finalised_if_published
if self.draft_changed? && !self.draft
self.finalised_at = Time.now
self.save
end
end
使用下面的建议,我将我的finalises_controller修改为:
def toggle_draft
@finalise = Finalise.find(params[:id])
@finalise.draft = false
# @finalise.finalised = Time.now
@finalise.save
redirect_to project_path(@finalise.scope.project.id])
end
在我的routes.rb中,我有:
resources :finalises do
patch '/toggle-draft', to: 'finalises#toggle_draft', as: 'toggle_draft'
end
当我尝试这个时,我收到的错误是:
No route matches {:action=>"toggle_draft", :controller=>"finalises", :id=>62} missing required keys: [:finalise_id]
我现在害怕尝试各种建议比我在开始这个帖子之前所做的更糟糕。我现在得到一个错误,说明未定义的方法最终确定&#39;。我没有一个名为finalize的方法。我有一个名为finalise.rb的模型
有没有人知道如何写一些东西来捕捉日期:草稿在db中等于false?
谢谢
答案 0 :(得分:3)
我认为您应该使用ActiveRecord回调,例如after_save
。在此回调中,您可以使用模块ActiveModel :: Dirty提供的方法来观察模型中的更改。
示例,在您的Finalize
模型中:
after_save :set_finalized_if_published
def set_finalized_if_published
if self.draft_changed? && !self.draft
self.finalized = Time.now
self.save
end
end
答案 1 :(得分:1)
密钥将在提交到数据库之后和更新之前拦截事件。解决此问题的一种方法是使用您编写的当前toggle_draft方法并向模型添加方法:
敲定控制器
def toggle_draft
@finalise = Finalise.find(params[:finalise_id])
@finalise.draft = false
if @finalise.save
redirect_to project_path(@finalise.project), notice: 'Successfully Updated'
else
redirect_to project_path(@finalise.project), alert: 'Not Updated'
end
end
然后在 finalise.rb模型文件中添加以下内容:
after_validation :set_publish_time
def set_publish_time
self.finalised = Time.now unless self.draft
end
如果您有任何问题,请告诉我
ALSO
对于您的路由问题,请尝试保留您的路线:
resources :finalises do
patch 'toggle-draft', to: 'finalises#toggle_draft', as: :toggle_draft
end
所以路线将是:
finalise_toggle_draft_path(@project.finalise)
并确保在创建项目记录时创建finalize记录,这样当您将变量加载到路径中时,它不会返回id的nil。
即
Product.rb模型
after_create :create_a_finalise
def create_a_finalise
self.finalise.create draft: true
end
其他选项:
如果使用此选项,请不要使用上述after_create代码
def create_a_finalise_dynamic(boolean)
self.finalise.create draft: boolean
end
将它放在产品#create动作中,但它适合。
EX,您可以在表单中添加一个额外的参数复选框,名为&#39; final_draft&#39;这不是在你的数据库中,也不是通过强大的参数来获知他们是否需要草案:
def create
@product = Product.new product_params
if @product.save
# if the checkbox is checked make the draft value false
boolean = params[:product][:final_draft] == 1 ? false : true
@product.create_a_finalise_dynamic boolean
redirect_to projects_path, notice: 'Created!'
else
render :new
end
end