我正在尝试使用Rails 4.1构建一个小费用跟踪应用。使用设计进行授权。费用和它的嵌套属性,注释属于用户。在模型中设置关联,并且费用与用户相关联。这是费用控制器:
class ExpensesController < ApplicationController
def new
@expense = Expense.new
@item = @expense.items.build
#@comment = @expense.comments.build
end
def index
@expenses = Expense.all
#@items = Item.where(:expense_id => @expense.id)
end
def show
@expense = Expense.find(params[:id])
@items = Item.where(:expense_id => @expense.id)
end
def create
@expense = current_user.expenses.new(expense_params)
respond_to do |format|
if @expense.save
ExpenseMailer.expense_submission(@expense).deliver
format.html { redirect_to @expense, notice: 'Expense Report Submitted.' }
format.json { render :show, status: :created, location: @expense }
else
format.html { render :new }
format.json { render json: @expense.errors, status: :unprocessable_entity }
end
end
end
def edit
@expense = Expense.find(params[:id])
end
def update
@expense = Expense.find(params[:id])
#@comment = @expense.comments.build
if @expense.update(expense_params)
#if @comment.save
#ExpenseMailer.comments_added(@expense).deliver
flash[:notice] = "Expense Report Updated"
redirect_to expenses_path
#else
# flash[:notice] = "Expense Report Updated"
#redirect_to expenses_path
##end
else
render 'edit'
end
end
构建注释属性的表单如下所示:
<%= nested_form_for (@expense) do |f| %>
<div class="form-group">
<%= f.label :state %><br />
<%= f.select :state, Expense.states, :include_blank => false, class: "form-control" %>
</div>
<%= f.fields_for :comments, @expense.comments.build do |comment| %>
<div class="form-group">
<%= comment.label :comment%>
<%= comment.text_area :comment, class: "form-control" %>
</div>
<%= comment.hidden_field :commenter %>
<% end %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
@ comment.commenter = current_user未将当前用户ID添加到数据库。我应该把它包含在费用控制器的某个地方吗?
答案 0 :(得分:2)
你必须添加:
@comment.commenter = current_user
下面的if语句。像这样:
def create
@article = Expense.find(params[:expense_id])
if @comment = @expense.comments.create(comment_params)
@comment.commenter = current_user
@comment.save
ExpenseMailer.comments_added(@expense).deliver
redirect_to expenses_path
end
end
然后再次保存评论。在当前代码中,您将使用新创建的对象覆盖@comment
对象:
@comment = @expense.comments.create(comment_params)
但您还没有在任何地方设置commenter
新对象。
答案 1 :(得分:0)
<强>模型强>
我只是尝试为您的strong params
创建更好的代码,但我无法解决如何在您的嵌套属性中包含该参数
因此,我建议您使用Comment
模型中的inverse_of:
方法对其进行正确排序:
#app/models/expense.rb
Class Expense < ActiveRecord::Base
belongs_to :user
has_many :comments, inverse_of: :expense
accepts_nested_attributes_for :comments
end
#app/models/comment.rb
Class Comment < ActiveRecord::Base
belongs_to :expense, inverse_of: :comments
before_create :populate_expense, on: :create
private
def populate_expense
self.commenter_id = self.expense.user_id
end
end
如果您正在填充accepts_nested_attributes_for
指令
<强>评论强>
我不明白为什么您为create
和expenses
控制器创建了两个comments
操作 - 控制器操作意味着独立于Model
我想说的是,如果您认为comments#create
属性创建会调用nested
控制器操作,那么您会被误认为 - 只会调用它当您通过Rails路由器向它发送请求时:)
如果您分别创建Comments
和Expenses
,则可以使用这两种不同的操作;但他们不会被彼此援引。只有模型方法可以被控制器调用(你不应该调用其他控制器方法)
如果您想在Comment
页面中创建expenses#show
,请按以下步骤进行设置:
#config/routes.rb
resources :expenses do
resources :comments #-> domain.com/expenses/:expense_id/comments/new
end
#app/controllers/expenses_controller.rb
Class CommentsController < ApplicationController
def new
@expense = Expense.find params[:expense_id]
@comment = @expense.comments.new
end
def create
@expense = Expense.find params[:expense_id]
@comment = @expense.comments.new(comment_params)
@comment.save
end
private
def comment_params
params.require(:comment).permit(:comment, :params).merge(commenter_id: current_user.id)
end
end
如果您想从expenses#show
页面创建评论,这将有效。如果您这样做,则需要确保调用comments#new
/ comments#create
操作,而不是expenses
控制器的操作