我有一个用户模型和一个消息模型。用户has_many消息和消息belongs_to用户。
在users_controller的一个方法中,我从API获取电子邮件数据,使用该数据初始化新消息(使用thisMessage = Message.new(messageId,senderName ...))。在控制器中,我多次执行此操作,并将这些消息存储在名为listOfMessages的Array中。到目前为止,这么好,我可以通过listOfMessages [0] .sender(发送者是消息模型属性)来使用消息的属性。
但是,当我刷新页面时,这些消息不会被保存。如果我在每次初始化一个新文件后尝试使用'thisMessage.save'将消息保存到数据库,我会得到错误“undefined method'[]'为nil:NilClass”。
我也试过'thisMessage.save!',我得到错误“未定义的方法'has_key?'为零:NilClass“
那么我应该如何保存这些消息呢?
消息模型
class Message < ActiveRecord::Base
belongs_to :user
def initialize(inputId, inputSender, inputSenderRealName, inputRecievedAt, inputSubject, inputContent, inputIsRead, inputIsReplied, inputImportanceLevel)
@emailId = inputId
@sender = inputSender
@senderRealName = inputSenderRealName
@recievedAt = inputRecievedAt
@subject = inputSubject
@content = inputContent
@isRead = inputIsRead
@isReplied = inputIsReplied
@importanceLevel = inputImportanceLevel
end
来自users_controller的方法我正在使用
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
最终目标是能够在其他地方执行“current_user.messages [1] .sender”之类的操作。 谢谢!
答案 0 :(得分:2)
ActiveRecord::Model
上的初始化方法。ActiveRecord模型已经采用了属性哈希:
User.new(name: 'Max', awesome: true)
如果属性存在,则将在模型实例上设置。初始化程序需要做很多工作,你不应该轻易破坏它。
如果您确实需要在初始化程序中执行某些操作,请确保调用super
并保持界面与模型所期望的相同。
def initalize(hash = {}, &block)
super
# do something custom here
end
但在大多数情况下,您可以使用回调或自定义属性设置器。
CONSTANTS
都是上限。 Ruby强制执行此操作。ModuleName
和ClassName
是CamelCase(也是一种常量)。variable_name
和attribute_name
为snake_case
。 Ruby并不关心 - 但社区确实如此。忽视这一点,你永远不能和那些很酷的孩子坐在一起。.update
和.assign_attributes
有几种方法可以更改模型实例,但注意更改内存中的模型实例和将更改提交到数据库之间的区别非常重要。
@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
)
这限制了外部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
https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services