【问题标题】:Object or Attribute Must Exist - Rails 5.2.2对象或属性必须存在 - Rails 5.2.2
【发布时间】:2019-01-15 15:50:58
【问题描述】:

我正在为我的学生创建一个小项目,但我遇到了一条错误消息我已经尝试了所有可能的解决方案,但没有取得进展。

图像是各种模型以及我如何实现各自的关联。以及 Create 的控制器方法和允许的参数。

我可以从我的服务器活动中清楚地看到所有属性值都已被捕获,但您收到一条错误消息,提示 “活动必须存在”

如果有人帮助我,我会很高兴。

提前致谢

问题更新

HTML 表单

<%= form_with(model: user_activity, local: true) do |frm| %>

    <div class="field">
        <%#= frm.label :activity_id %><br />
        <%= select_tag 'activity_id', options_for_select(Activity.all.collect{ |u| [u.activity_name, u.id] }) %>
    </div>

    <div class="field">
        <%= frm.label(get_user_activity_date) %><br />
        <%= frm.date_field :user_activity_date, autofocus: true%>
    </div>

    <div class="field">
        <%= frm.label(get_user_activity_start_time) %><br />
        <%= frm.time_field :user_activity_start, autofocus: true %>
    </div>

    <div class="field">
        <%= frm.label(get_user_activity_end_time) %><br />
        <%= frm.time_field :user_activity_end, autofocus: true, autocomplete: "age" %>
    </div>

    <div class="field">
        <%= frm.label(get_user_activity_note) %><br />
        <%= frm.text_area :user_activity_note, autofocus: true %>
    </div>

    <div class="actions">
        <%= frm.submit %>
    </div>
<% end %>

服务器日志

Started POST "/user_activities" for 127.0.0.1 at 2019-01-16 06:45:44 +0100
Processing by UserActivitiesController#create as HTML
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"qfcYksfgoAzNaO4ZQ6rsG9WFV6waUywbsaOCTePsjpV4PmXp0tofWfS01as6ArrdwyNtthCt5aLs2tNXavD/7A==", "activity_id"=>"3", "user_activity"=>{"user_activity_date"=>"2018-12-31", "user_activity_start"=>"12:02", "user_activity_end"=>"22:02", "user_activity_note"=>"Record User Activity"}

仍在努力解决问题

我已经尝试了您的大部分建议,但仍然没有进展,但是当我按照以下代码中的指示尝试以下操作时,我得到了一个奇怪的结果,但无法插入到数据库中

def new
    @user_activity = UserActivity.new
end

def create
    # @user_activity = UserActivity.new(user_activity_params)
    activity_id = user_activity_params[:activity_id] #fetch this value from params as it comes

    puts "The activity ID which is received is -> #{activity_id.to_i}"
    # puts current_user.user_id

    user_activity_date = user_activity_params[:user_activity_date]
    puts "Date -> #{user_activity_date}"

    user_activity_start = user_activity_params[:user_activity_start]
    puts "Start Time -> #{user_activity_start}"

    user_activity_end = user_activity_params[:user_activity_end]
    puts "End Time -> #{user_activity_end}"

    user_activity_note = user_activity_params[:user_activity_note]
    puts "Activity Note -> #{user_activity_note}"

    @user_activity = current_user.user_activities.new(activity_id:activity_id.to_i, user_activity_date: user_activity_date.to_date,user_activity_start: user_activity_start.to_time,user_activity_end: user_activity_end.to_time,                            user_activity_note: user_activity_note )
end

参数

def user_activity_params

    params.require(:user_activity).permit(:activity_id, :user_activity_date, :user_activity_start, :user_activity_end, :user_activity_note)

    # params.fetch(:user_activity, {}).permit(:user_id, :activity_id, user_activity: [:user_activity_date, :user_activity_start, :user_activity_end, :user_activity_note])

    # params.permit(:user_id, :activity_id, :user_activity_date, :user_activity_start, :user_activity_end, :user_activity_note)

end

服务器日志

Started POST "/user_activities" for 127.0.0.1 at 2019-01-16 21:15:48 +0100
Processing by UserActivitiesController#create as HTML
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"7v79xk6TW0IHNjkno+iXwzIYqqBjBMxCSodddPHUmKI/N4C9W6nkFz7qApXaQMEFJL6Qumn6BfsX/gxueMjp2w==", "user_activity"=>{"activity_id"=>"1", "user_activity_date"=>"2019-01-15", "user_activity_start"=>"20:14", "user_activity_end"=>"21:15", "user_activity_note"=>"testing to see if values can be retrieved"}, "commit"=>"Create User activity"}
    Activity ID -> 1
    Date -> 2019-01-15
    Start Time -> 20:14
    End Time -> 21:15
    Activity Note -> testing to see if values can be retrieved

        User Load (0.9ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
        ↳ app/controllers/user_activities_controller.rb:46
        (0.5ms)  BEGIN
        ↳ app/controllers/user_activities_controller.rb:46
        UserActivity Create (3.0ms)  INSERT INTO `user_activities` (`created_at`, `updated_at`, `user_id`) VALUES ('2019-01-16 20:15:49', '2019-01-16 20:15:49', 1)
        ↳ app/controllers/user_activities_controller.rb:46
        (0.5ms)  ROLLBACK
        ↳ app/controllers/user_activities_controller.rb:46
Completed 500 Internal Server Error in 125ms (ActiveRecord: 12.4ms)

ActiveRecord::NotNullViolation (Mysql2::Error: Field 'user_activity_date' doesn't have a default value: INSERT INTO `user_activities` (`created_at`, `updated_at`, `user_id`) VALUES ('2019-01-16 20:15:49', '2019-01-16 20:15:49', 1)):

app/controllers/user_activities_controller.rb:46:in `create'

【问题讨论】:

  • 你如何将数据属性传递给 user_activity,我看到构建时没有调用任何参数。 user_activity_params 方法也存在于 user_activity_controller? 中。模型代码看起来不错,同时在控制器中创建 user_activity 确保活动 id 和用户 id 存在。
  • 不要发布图片,而是发布格式化文本。

  • @Bijendra 请 create 和 user_activity_params 方法都在 UserActivity 控制器内。我正在使用上面的 html 将 Activity 对象 id (activity_id) 传递给控制器​​。
  • @BismarkAttaFrimpong 您正在将 activity_id 传递给控制器​​,现在您需要确保 activity_id 从控制器传递到数据库。缺少那部分代码。打开 Rails 控制台,执行下面的代码来了解一下。 1>user = User.last 2> obj1 = user.user_activities.build 3> obj1.save 是什么错误?现在试试 4> obj2 = user.user_activities.build(activity_id: Activity.last.id) 5> obj2.save 这里的 o/p 是什么?对格式感到抱歉。

标签: ruby-on-rails ruby rails-activerecord ruby-on-rails-5.2


【解决方案1】:

您可以尝试将activity_id 提供给新的user_activity

@user_activity = current_user.user_activities.build(activity_id: params[:activity_id])

【讨论】:

  • 请问您将 activity_id 提供给新的 user_activity 是什么意思?我已经尝试过您的解决方案,但仍然收到“Activity 必须存在”的错误消息。
【解决方案2】:
#user.rb

class User < ApplicationRecord
  has_many :user_activities
  has_many :activities, through: :user_activities
end

#activity.rb

class Activity < ApplicationRecord
  has_many :user_activities
  has_many :users, through: :user_activities
end

#user_activity.rb

class UserActivity < ApplicationRecord
  belongs_to :user
  belongs_to :activity
end

我将您的模型复制到一个小型应用程序中,并尝试从 Rails 控制台进行操作。这应该会让你更好地理解

Loading development environment (Rails 5.2.2)
2.4.1 :002 > Activity.last
   (0.3ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  Activity Load (0.2ms)  SELECT  `activities`.* FROM `activities` ORDER BY `activities`.`id` DESC LIMIT 1
 => nil 
2.4.1 :004 > obj = Activity.new(name: "Cricket", activity_type: "Sports")
 => #<Activity id: nil, name: "Cricket", created_at: nil, updated_at: nil, activity_type: "Sports"> 
2.4.1 :005 > obj.save
   (0.2ms)  BEGIN
  Activity Create (0.4ms)  INSERT INTO `activities` (`name`, `created_at`, `updated_at`, `activity_type`) VALUES ('Cricket', '2019-01-16 05:20:10', '2019-01-16 05:20:10', 'Sports')
   (6.4ms)  COMMIT
 => true 
2.4.1 :007 > obj1 = User.new(name: "user1",city: "city1") 
 => #<User id: nil, name: "user1", role_id: nil, created_at: nil, updated_at: nil, city: "city1"> 
2.4.1 :008 > obj1.save
   (0.2ms)  BEGIN
  User Create (0.4ms)  INSERT INTO `users` (`name`, `created_at`, `updated_at`, `city`) VALUES ('user1', '2019-01-16 05:20:59', '2019-01-16 05:20:59', 'city1')
   (5.9ms)  COMMIT
 => true

所以我在下面的操作之前创建了一些背景数据,

2.4.1 :001 > user = User.last
(0.3ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
    User Load (0.3ms)  SELECT  `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
   => #<User id: 1, name: "user1", role_id: nil, created_at: "2019-01-16 05:20:59", updated_at: "2019-01-16 05:20:59", city: "city1"> 
  2.4.1 :002 > obj1 = user.user_activities.build
   => #<UserActivity id: nil, user_id: "1", activity_id: nil, created_at: nil, updated_at: nil> 
  2.4.1 :003 > obj1.save
     (0.3ms)  BEGIN
     (0.2ms)  ROLLBACK
   => false 
  2.4.1 :004 > obj1.errors.full_messages
   => ["Activity must exist"] 
  2.4.1 :005 > obj1 = user.user_activities.build(activity_id: Activity.last.id)
    Activity Load (0.3ms)  SELECT  `activities`.* FROM `activities` ORDER BY `activities`.`id` DESC LIMIT 1
   => #<UserActivity id: nil, user_id: "1", activity_id: "1", created_at: nil, updated_at: nil> 
  2.4.1 :006 > obj1.save
     (0.2ms)  BEGIN
    Activity Load (0.3ms)  SELECT  `activities`.* FROM `activities` WHERE `activities`.`id` = 1 LIMIT 1
    UserActivity Create (0.2ms)  INSERT INTO `user_activities` (`user_id`, `activity_id`, `created_at`, `updated_at`) VALUES ('1', '1', '2019-01-16 05:23:32', '2019-01-16 05:23:32')
     (5.6ms)  COMMIT
   => true 

[“Activity 必须存在”],在控制台中查找此错误,原因是 activity_id 未传递给 user_activity 对象。现在更新控制器中的代码

activity_id = #fetch this value from params as it comes
@user_activity = current_user.user_activities.new(activity_id: activity_id)

我看到你有具有多个属性的 user_activity_params 方法,一旦上面的代码工作,如果需要,用新行测试它。

 @user_activity = current_user.user_activities.new(user_activity_params)

【讨论】:

  • @Bijindra 我已经查看了测试结果,我也有类似的事情,就像 @andriy-baran 建议的那样,但我已经意识到即使我可以从 Rails 服务器控制台看到它,表单中选择的活动 ID 也不会传递给控制器​​中的参数
  • 使用 html 表单代码更新您的问题并发布从服务器日志@BismarkAttaFrimpong 收到的参数
  • @BismarkAttaFrimpong 我可以看到 activity_id 在您共享的参数中传递,按照建议在 .build(activity_id: params[:activity_id] 中使用它
  • 我仍然无法将参数传递给控制器​​中的 user_activity_params。或者我可能做错了什么?这就是我的新方法被称为 def new @user_activity = UserActivity.new #user_activity = current_user.user_activities.build(user_activity_params) end 请帮我检查两者之间,哪一个合适。谢谢
  • activity_id =user_activity_params[:activity_id] @user_activity = current_user.user_activities.new(activity_id: activity_id) 有效,但随后它不断抛出错误其他参数为空
【解决方案3】:

根据帖子中提到的描述和发布的相关日志图像,似乎 activity_id 正在传递给控制器​​,但按照控制器参数中声明的错误顺序。

修改代码如下

对于 HTML

<div class="field">
    <%#= frm.label :activity_id %><br />
    <%= select_tag 'user_activity[activity_id]', options_for_select(Activity.all.collect{ |u| [u.activity_name, u.id] }) %>
</div>

对于控制器

def create
    @user_activity = current_user.user_activities.build(user_activity_params)
end

现在 activity_id 将在 user_activity 中传递,因此 params 将按照 activity_params 方法中的说明进行解析。

【讨论】:

  • 我已经尝试了您的解决方案,但控制器仍然没有通过 user_activity_params 接收参数,即使我可以在服务器日志中看到它们传递给它
  • user_actitvity_params 和 create 方法是否在同一个控制器中?
  • 是的。它们都在 UserActivity 控制器中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 2016-02-24
  • 2019-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多