Using Struct with Rails
I came across this messaging tutorial recently, and was intrigued by the use of Struct.new. With a bit of help from google and SO I've learnt a bit more about the use of Struct in Ruby, but I would like to know a bit more about its use in Rails. In the tutorial, there is a folder model which stores the user's recieved messages:
class Folder < ActiveRecord::Base
acts_as_tree
belongs_to :user
has_many :messages, :class_name => "MessageCopy"
end
The 'inbox' folder is created when a new user is created:
class User < ActiveRecord::Base
has_many :sent_messages, :class_name => "Message", :foreign_key => "author_id"
开发者_运维技巧 has_many :received_messages, :class_name => "MessageCopy", :foreign_key => "recipient_id"
has_many :folders
before_create :build_inbox
def inbox
folders.find_by_name("Inbox")
end
def build_inbox
folders.build(:name => "Inbox")
end
end
However, the 'trash' folder is created on the fly using Struct.new:
class MailboxController < ApplicationController
def index
@folder = current_user.inbox
show
render :action => "show"
end
def show
@folder ||= current_user.folders.find(params[:id])
@messages = @folder.messages.not_deleted
end
def trash
@folder = Struct.new(:name, :user_id).new("Trash", current_user.id)
@messages = current_user.received_messages.deleted
render :action => "show"
end
end
What benefits does using Struct with Rails have? Why it is used in this tutorial to created the 'trash' folder and not the 'inbox' folder (which could also be built when the user is created)? Thanks for the help, I haven't come across too much online yet about when Struct can/should be used with Rails!
There is no benefit, just a certain reasoning behind it:
- A user can own folders.
- The trash in this example is a virtual folder, it contains all messages that have been flagged as deleted.
To keep your views working for both cases the author decided to create a fake-folder object (one which does not have all the active-record stuff, so it can't be saved etc). He then exposes it to the views.
<%= @folder.name %>
will then work, independent of whether it is that fake-folder or a real folder.
精彩评论