使用相同的表单轨道在create方法中更新和保存数据库

时间:2022-12-22 01:20:53

I am trying to use the same form to create a new database entry, display current DB information, and now update the DB information, but am stuck trying to patch in the create method within the controller. I have tried using first_or_initialize and find_or_initialize_by_name, but cant seem to get them to work for this situation. I was thinking of trying a if something.nil? / else type of design. I am new at this and any help is appreciated!

我试图使用相同的表单来创建一个新的数据库条目,显示当前的数据库信息,现在更新数据库信息,但我试图修改控制器内的create方法。我尝试过使用first_or_initialize和find_or_initialize_by_name,但似乎无法让它们适应这种情况。我在考虑尝试if something.nil? / else设计​​类型。我是新来的,任何帮助表示赞赏!

This is my controller (working currently to create new DB):

这是我的控制器(目前正在创建新的DB):

    def create
     params[:student].each do |student_id, attendance_type|
      attendance = Attendance.new
      attendance.attendance_type = attendance_type.to_i
      attendance.student_id = student_id
      attendance.event_id = params[:event_id]
      attendance.save
    end
     redirect_to :back
   end

HTML:

    <tbody>
     <% @students.each do |student| %>
      <form class="form-group" action="/events/<%= @event.id %>/attendances" method="post">
      <tr>
      <div class="checkbox">
        <td style="white-space:normal;"><%= link_to student.name, student_path(student.id) %></td>

        <% attendance = student.attendances.find_by_event_id(@event.id) %>
        <% if attendance.blank? || attendance.attendance_type == 1 %>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" checked="checked" id="inlineRadio1" value="1"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio2" value="2"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio3" value="3"></label></td>
        <% elsif attendance.attendance_type == 2 %>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio1" value="1"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" checked="checked" id="inlineRadio2" value="2"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio3" value="3"></label></td>
        <% else attendance.attendance_type == 3 %>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio1" value="1"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" id="inlineRadio2" value="2"></label></td>
          <td style="white-space:normal;"><label class="radio-inline"><input type="radio" name="student[<%= student.id %>]" checked="checked" id="inlineRadio3" value="3"></label></td>
        <% end %>
      </div>
    <% end %>
    </tr>
        <tr><%= button_to 'Submit', :class => 'btn btn-primary' %></tr>

</form>
    </tbody>

Thank you in advance!

先感谢您!

1 个解决方案

#1


Hopefully this is your missing piece. I do not believe it will help with efficiency. I will explain after.

希望这是你失踪的一块。我认为这不会有助于提高效率。我会在之后解释。

Using an attribute already existing for your model I would do the following to either find or create an attendance object for student with the id 10.

使用已存在的模型属性,我将执行以下操作,为ID为10的学生查找或创建出勤对象。

Attendance.where(:student_id => 10).first_or_create do |attendance|
  attendance.event_id = 3 #arbitrary
  attendance.attendance_type = 2 #arbitrary
end

OR

attendance = Attendance.where(:student_id => 10).first_or_initialize
# a bunch of ways to set attributes
# ... and then
attendance.save

Now, why this may be inefficient. If you are going through each student parameter and looping through some attribute you will incur multiple calls. For example, for 100 students you will end up doing 100 separate queries if you loop for a first_or_initialize on every student attribute set. What I suggest is mapping all of the parameters that you require together into one array, doing a where query and then looping through the array. Put them all into one create call as an array, and BAM you cut yourself some serious ActiveRecord overhead.

现在,为什么这可能效率低下。如果您浏览每个学生参数并循环浏览某些属性,则会产生多个调用。例如,对于100名学生,如果您在每个学生属性集上循环使用first_or_initialize,则最终将执行100个单独的查询。我建议将所需的所有参数一起映射到一个数组中,执行where查询然后循环遍历数组。将它们全部放入一个创建调用作为数组,BAM你自己削减了一些严重的ActiveRecord开销。

#Just giving some context to the student param keys
student_ids = params[:student].keys 
#Query for all student ids
attendances = Attendance.where(student_id: student_ids) 
#Get a list of ids by filtering out all of the existing ids
new_student_ids = student_ids - attendances.map{|a| a.student_id}
#Create an array to carry your hashes
attendances = Array.new
#Cycle through all of your non-created ids and build you create list
new_student_ids.each do |id|
  attendances << {#assign all values as a hash by grabbing them from params[:student] using the iterating id}
end  
#Create a bunch at once
Attendance.create attendances

#1


Hopefully this is your missing piece. I do not believe it will help with efficiency. I will explain after.

希望这是你失踪的一块。我认为这不会有助于提高效率。我会在之后解释。

Using an attribute already existing for your model I would do the following to either find or create an attendance object for student with the id 10.

使用已存在的模型属性,我将执行以下操作,为ID为10的学生查找或创建出勤对象。

Attendance.where(:student_id => 10).first_or_create do |attendance|
  attendance.event_id = 3 #arbitrary
  attendance.attendance_type = 2 #arbitrary
end

OR

attendance = Attendance.where(:student_id => 10).first_or_initialize
# a bunch of ways to set attributes
# ... and then
attendance.save

Now, why this may be inefficient. If you are going through each student parameter and looping through some attribute you will incur multiple calls. For example, for 100 students you will end up doing 100 separate queries if you loop for a first_or_initialize on every student attribute set. What I suggest is mapping all of the parameters that you require together into one array, doing a where query and then looping through the array. Put them all into one create call as an array, and BAM you cut yourself some serious ActiveRecord overhead.

现在,为什么这可能效率低下。如果您浏览每个学生参数并循环浏览某些属性,则会产生多个调用。例如,对于100名学生,如果您在每个学生属性集上循环使用first_or_initialize,则最终将执行100个单独的查询。我建议将所需的所有参数一起映射到一个数组中,执行where查询然后循环遍历数组。将它们全部放入一个创建调用作为数组,BAM你自己削减了一些严重的ActiveRecord开销。

#Just giving some context to the student param keys
student_ids = params[:student].keys 
#Query for all student ids
attendances = Attendance.where(student_id: student_ids) 
#Get a list of ids by filtering out all of the existing ids
new_student_ids = student_ids - attendances.map{|a| a.student_id}
#Create an array to carry your hashes
attendances = Array.new
#Cycle through all of your non-created ids and build you create list
new_student_ids.each do |id|
  attendances << {#assign all values as a hash by grabbing them from params[:student] using the iterating id}
end  
#Create a bunch at once
Attendance.create attendances