问题
I'd like to be able to loop through the model based on its current state.
I've created fairly simple states for my model as follows:
models/job.rb
class Job < ActiveRecord::Base
has_many :events, class_name: "JobEvent"
STATES = %w[bids in_progress complete canceled]
delegate :bids?, :in_progress?, :complete?, :canceled?, to: :current_state
def current_state
(events.last.try(:state) || STATES.first).inquiry
end
end
and
models/job_event.rb
class JobEvent < ActiveRecord::Base
belongs_to :job
attr_accessible :state
validates_presence_of :job_id
validates_inclusion_of :state, in: Order::STATES
def self.with_last_state(state)
order("id desc").group("job_id").having(state: state)
end
end
States works - I can change the state just fine. I'd like to be able to loop through the models based on its current state. Not sure about the best way to go about this. I'm new at scoping and am attempting to loop through my states as follows (not working):
views/index.html.erb
<% @current_state_jobs.each do |job| %>
<tr>
<td><%= link_to job.job_number, job %></td>
</tr>
<% end %>
Its seems like the above would work - but I'm getting the following error: undefined method 'each' for nil:NilClass
Should I focus on scopes or maybe define each state as a method in the controller? Maybe I should put an if then statement at the beginning of the loop? Any ideas or recommended reading?
--- UPDATE --- SOLUTION FOUND ---
I ended up adding instances in my controller index method for each state. Then added a tabbed view to my index to loop through each state at a time.
For example:
class JobsController < ApplicationController
def index
@all = Job.where(:state => ['bids', 'in_progress', 'complete']) #all job states
@bids = Job.where(:state => ['bids'])
... and so on for each state
...
回答1:
Well, your undefined method error is because @current_state_jobs is nil when you expected it to be a collection. You need to assign it some value in your controller's index method.
I'm not sure your question is clear enough. Do you want to loop through all Job instances and perform actions specific to each one's state, or do you want to get all jobs for one particular state and loop through those?
If it's the latter, you need a scope or class method that you could use to grab jobs for that state. Perhaps something like this:
class Job < ActiveRecord::Base
def self.with_state(state)
joins(:events).where("job_event.state = ?",state)
end
end
@current_state_jobs = Job.with_state("in_progress")
(You need the current_state instance method for this, unless you're using it elsewhere).
来源:https://stackoverflow.com/questions/13885750/loop-through-states-scope-ruby-rails