Ruby on rails 无法更改Rails控制器中的变量属性
我已经有一段时间没有使用Rails了,有些事情我想澄清一下 所以@符号表示,该特定变量将可在该控制器视图中访问。对吗 意思是如果我有一条路线 获取“/admin/user:id”到:“adminuser” 这意味着,无论何时,只要我转到路由,它就会转到路由“/admin/user:id”,然后它就可以访问该控制器中的所有@变量。对吗 这是我遇到的一个小问题,通常是JavaScript中的一个简单if语句 例如,假设我有一个用户模型,我想显示一个小朋友和朋友的列表。名字,姓氏,最喜欢的食物。我可以通过简单的操作来证明这一点 管理员/控制器 然后在我看来Ruby on rails 无法更改Rails控制器中的变量属性,ruby-on-rails,Ruby On Rails,我已经有一段时间没有使用Rails了,有些事情我想澄清一下 所以@符号表示,该特定变量将可在该控制器视图中访问。对吗 意思是如果我有一条路线 获取“/admin/user:id”到:“adminuser” 这意味着,无论何时,只要我转到路由,它就会转到路由“/admin/user:id”,然后它就可以访问该控制器中的所有@变量。对吗 这是我遇到的一个小问题,通常是JavaScript中的一个简单if语句 例如,假设我有一个用户模型,我想显示一个小朋友和朋友的列表。名字,姓氏,最喜欢的食物。我可以
<h1><%= @user.name %>'s Friends List</h1>
<table>
<tr><%= @user.user_friends.first.friend.first_name %></tr>
<tr><%= @user.user_friends.first.friend.last_name %></tr>
<tr><%= @user.user_friends.first.friend.favourite_food %></tr>
</table>
我想我可以创建另一个@variable,但我认为这是一个更好的方法,因为创建不必要的宽范围变量并不好 此逻辑属于视图,请执行以下操作
<% if @user.user_friends.any? %>
<tr><%= @user.user_friends.first.friend.first_name %></tr>
<tr><%= @user.user_friends.first.friend.last_name %></tr>
<tr><%= @user.user_friends.first.friend.favourite_food %></tr>
<% else %>
<tr>N/A</tr>
<tr>N/A</tr>
<tr>N/A</tr>
<% end %>
我将用三元运算符将该逻辑直接放在视图上,如下所示:
<table>
<tr><%= @user.user_friends.nil? ? "N/A" : @user.user_friends.first.friend.first_name %></tr>
<tr><%= @user.user_friends.nil? ? "N/A" : @user.user_friends.first.friend.last_name %></tr>
<tr><%= @user.user_friends.nil? ? "N/A" : @user.user_friends.first.friend.favourite_food %></tr>
</table>
就我个人而言,我在这种情况下使用presenter模式。因此,在控制器中,您可以执行以下操作:
def user
@user = user.find_by(:id => params[:id])
@user_presenter = UserPresenter.new(self)
end
然后在你看来,你会做如下事情:
<h1><%= @user.name %>'s Friends List</h1>
@user_presenter.friends_list
我喜欢这样做,因为:
我的视图对我的模型层一无所知我喜欢分离
它让我的视图变得超级愚蠢,在视图中没有逻辑,这是我更喜欢的——在我的应用程序中,视图只有html标记,我使用HAML和调用演示者
如果我对我的模型做了任何更改,只要我的UserPresenter尊重friends_list界面,我就不必返回视图进行更改
我发现测试普通的ruby对象要比测试各种Rails组件、控制器、视图等容易得多。我所有的演示者都是PORO。
有一个关于演示者的好方法。在该域中,您有两个实体:UserWithFriends和UserWithoutFriends。因此,您需要创建一个UserFactory
class UserWithFriends < User
def initialize(user)
@user = user
end
def friend_first_name
@user.friends.first.first_name
end
def friend_last_name
@user.friends.first.last_name
end
def friend_favourite_food
@user.friends.first.favourite_food
end
end
class UserWithoutFriends < User
def initialize(user)
@user = user
end
def friend_first_name
"N/A"
end
def friend_last_name
"N/A"
end
def friend_favourite_food
"N/A"
end
end
class UserFactory
def initialize(user)
@user = user
end
def create
if @user.friends.any?
UserWithFriends(@user).new
else
UserWithoutFriends(@user).new
end
end
end
因此,在视图中,您只需这样做
<h1><%= @user.name %>'s Friends List</h1>
<table>
<tr><%= @user.friend_first_name %></tr>
<tr><%= @user.friend_last_name %></tr>
<tr><%= @user.friend_favourite_food %></tr>
</table>
哦,是的,我忘了这个。是的,我们现在的控制器大约有60行,但是它需要大量的数学运算和转换秒数、日期等。如果你只是为了显示目的而转换,你应该将逻辑移到你的视图中,更好的是,移到视图帮助器中。user.findparams[:id]就足够了
<h1><%= @user.name %>'s Friends List</h1>
@user_presenter.friends_list
class UserWithFriends < User
def initialize(user)
@user = user
end
def friend_first_name
@user.friends.first.first_name
end
def friend_last_name
@user.friends.first.last_name
end
def friend_favourite_food
@user.friends.first.favourite_food
end
end
class UserWithoutFriends < User
def initialize(user)
@user = user
end
def friend_first_name
"N/A"
end
def friend_last_name
"N/A"
end
def friend_favourite_food
"N/A"
end
end
class UserFactory
def initialize(user)
@user = user
end
def create
if @user.friends.any?
UserWithFriends(@user).new
else
UserWithoutFriends(@user).new
end
end
end
def user
@user = UserFactory.new(user.find_by(:id => params[:id])).create
end
<h1><%= @user.name %>'s Friends List</h1>
<table>
<tr><%= @user.friend_first_name %></tr>
<tr><%= @user.friend_last_name %></tr>
<tr><%= @user.friend_favourite_food %></tr>
</table>