Ruby on rails Rails:调用model.new后如何将对象保存到模型?

Ruby on rails Rails:调用model.new后如何将对象保存到模型?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个用户模型和一个消息模型。用户有许多消息,消息属于用户。 在users\u controller的一种方法中,我从API获取电子邮件数据,用该数据初始化一条新消息(使用thisMessage=Message.new(messageId,senderName…)。在控制器中,我多次这样做,并将这些消息存储在一个名为listOfMessages的数组中。到目前为止,很好,我可以通过执行listOfMessages[0]来使用消息的属性。例如,sender(sender是消息模型属性)。 但是

我有一个用户模型和一个消息模型。用户有许多消息,消息属于用户。

在users\u controller的一种方法中,我从API获取电子邮件数据,用该数据初始化一条新消息(使用thisMessage=Message.new(messageId,senderName…)。在控制器中,我多次这样做,并将这些消息存储在一个名为listOfMessages的数组中。到目前为止,很好,我可以通过执行listOfMessages[0]来使用消息的属性。例如,sender(sender是消息模型属性)。

但是,当我刷新页面时,这些消息当然不会被保存。如果在每次初始化新消息后尝试使用“thisMessage.save”将消息保存到数据库,则会出现错误“nil:NilClass的未定义方法”[]。

我还尝试了“thisMessage.save!”,对于nil:NilClass,我得到了错误“undefined method'has_key?”

那么我应该如何保存这些消息呢?

消息模型

class消息
来自用户的方法\u我正在使用的控制器

def messageList
    @user = current_user
    if @user.current_message == nil
        @user.current_message = 0
    else

    end



    puts "Need Loading " + @user.needsLoading.to_s
    @listOfMessages = Array.new
    messageIdList = Array.new

    --API stuff removed--

        body1 = singleMessage['bodies'][0]['content']
        senderName = singleMessage['addresses']['from'][0]['email']
        senderActualName = singleMessage['addresses']['from'][0]['name']
        recieveTime = singleMessage['sent_at']
        subjectText = singleMessage['subject']
        isRead = singleMessage['flags']['seen']
        hasReplied =  singleMessage['flags']['answered']


        thisMessage = Message.new(messageId, senderName, senderActualName, recieveTime, subjectText, body1, isRead, hasReplied, 0)

        @listOfMessages << thisMessage
        thisMessage.save
    }

    puts @user.messages.length
    @responseText = response
    puts @user.needsLoading.to_s
    puts @user.current_message
    @user.update_column(:needsLoading, 1)



end
def消息列表
@用户=当前用户
如果@user.current_message==nil
@user.current_消息=0
其他的
结束
将“需要加载”+@user.needsLoading.to_
@listOfMessages=Array.new
messageIdList=Array.new
--已删除API内容--
body1=singleMessage['Bodys'][0]['content']
senderName=singleMessage['addresses']['from'][0]['email']
senderActualName=singleMessage['addresses']['from'][0]['name']
ReceiveTime=singleMessage['Send_at']
subjectText=singleMessage['subject']
isRead=singleMessage['flags']['seen']
HasResped=singleMessage['flags']['Resped']
thisMessage=Message.new(messageId,senderName,senderActualName,receiveTime,subjectText,body1,isRead,hasReplied,0)
@信息列表1。不要覆盖
ActiveRecord::Model
上的initialize方法。 ActiveRecord模型已采用散列属性:

User.new(name: 'Max', awesome: true)
如果属性存在,将在模型实例上设置该属性。初始值设定项为它做了大量的工作,您不应该轻描淡写地使用它

如果您真的需要在初始值设定项中执行某些操作,请确保调用
super
,并使接口与预期的模型相同

def initalize(hash = {}, &block)
  super
  # do something custom here
end
但在大多数情况下,您可以使用回调或自定义属性设置器

2.遵循ruby约定。 Ruby和Rails在命名方面有非常简单和强大的约定:

  • 常量
    都是大写。Ruby实现了这一点
  • ModuleName
    ClassName
    是CamelCase(也是一种常量)
  • variable\u name
    attribute\u name
    snake\u case
    。Ruby不在乎——但社区在乎。忽视这一点,你将永远无法与酷孩子坐在一起
3.
。更新
。分配属性
有几种方法可以更改模型实例,但重要的是要注意在内存中更改模型实例和将更改提交到数据库之间的区别

@order = Order.new

# change a single attribute.
@order.total = 999 

# Update multiple attributes at once
@order.assign_attributes(
  total: 669,
  shipping_method: 'FEDEX'
) 

# So far we have only updated the instance in memory.
@order.save # Commit the changes to the database

# We can also update the database straight away.

@order.update_attribute(:total, 999) # one attribute at a time

# or with a hash.
@order.update(
  total: 669,
  shipping_method: 'FEDEX'
) 

# Using related objects works the same:
@order.update(
  customer: @customer
) 

# Note that this will also save the related object to the database.
@order.update(
  customer: Customer.new
) 
4.使用服务对象从API调用创建模型实例。 这限制了外部api和应用程序之间的接触点数量。而且它们真的很容易测试

# Import a message from SomeApi
class MessageImportService

  def initialize(client = MyApi)
    @client = client
  end
  
  # @return [Array]
  def call
    data = @client.call_some_api_method || []
    data.map do |raw_msg|
      Message.new(
        body1 : raw_msg['bodies'][0]['content'],
        sender_name : raw_msg['addresses']['from'][0]['email'],
        sender_actual_aame : raw_msg['addresses']['from'][0]['name'],
      ) 
    end
  end
end
通过控制器,您可以执行以下操作:

@messages = MessageImportService.new.call

谢谢!重写rails初始化方法是我的问题。一旦我摆脱了初始化方法,保存工作就完美了!
@messages = MessageImportService.new.call