Reputation: 45
Hello (hopefully) omniscient Rails folks ;)
I'm currently trying to generate a set of radio buttons from an instance variable in one of my models. Because the MVC pattern prohibits passing data from models directly into the views, I somehow have to include the controller as kind of a middleman. The problem is that I can't access the instance variable of my model even though I use 'attr_reader :valid_statuses'. Therefore it's also not possible to pass the data down to my view...
This is how my user model looks like at the moment. The '@valid_statuses' array contains the strings which should be used to generate the radio buttons.
class User < ApplicationRecord
attr_reader :valid_statuses
@valid_statuses = %w(new editor admin blocked)
validates :status, inclusion: { in: @valid_statuses }
end
The controller looks like this. @user is not nil, but @valid_statuses is
class UsersController < ApplicationController
...
def set_user
@user = User.find(params[:id])
@valid_statuses = @user.valid_statuses
end
...
end
The _form.html.erb:
<div class="field">
<%= f.label :status %>
<% @valid_statuses.each do |item| %>
<%= f.radio_button :status, item %> <%= item %><br />
<% end %>
</div>
I would be very greateful if someone knows the answer to this and could share it with me and the rest of the world! Thanks!
Upvotes: 1
Views: 690
Reputation: 54213
Valid statuses don't change from one User to another.
So you define @valid_statuses
inside the class User. @valid_statuses
isn't defined for a specific @user
, but for the whole class. attr_reader :valid_statuses
tries to find the instance variable @valid_statuses
of @user
, which hasn't been defined.
Here's a possible modification :
class User < ApplicationRecord
@valid_statuses = %w(new editor admin blocked)
validates :status, inclusion: { in: @valid_statuses }
def self.valid_statuses
@valid_statuses
end
end
and in your views :
User.valid_statuses
Upvotes: 1
Reputation: 3722
in this case, you have to use constants (if you wanna only fix your code):
model:
class User < ApplicationRecord
VALID_STATUSES = %w(new editor admin blocked)
validates :status, inclusion: { in: VALID_STATUSES }
end
controller:
class UsersController < ApplicationController
...
def set_user
@user = User.find(params[:id])
end
...
end
view:
<div class="field">
<%= f.label :status %>
<% User::VALID_STATUSES.each do |item| %>
<%= f.radio_button :status, item %> <%= item %><br />
<% end %>
</div>
BUT I better use enum
with name status
:
model:
class User < ApplicationRecord
enum status: [:new, :editor, :admin, :blocked]
end
Upvotes: 1