我想传递一个额外的字段,比如说item_id到这些代码行(控制器和模型):
# transactions_controller.rb (controller)
@transaction = Transaction.new(app_token: params[:token])
# transaction.rb (model)
def app_token=(token)
write_attribute(:app_token, token)
# I want to add a few more lines of code here so that I can manipulate item_id
end
这意味着,我希望我的item_id从控制器传递到模型,以便我可以操作它在模型中进行一些自定义。
这样做的最佳方法是什么(基于上面的代码)?
===更新于2014年9月1日,了解更多详情===
我有购物车和交易的关联,其中购物车has_many交易和交易belongs_to cart;下面是控制器;
# transactions_controller.rb (controller)
def new
@transaction = Transaction.new(app_token: params[:token])
end
虽然以下方法在模型中:
# transaction.rb (model)
def app_token=(token)
write_attribute(:app_token, token)
# I want to add a few more lines of code here so that I can manipulate cart.id
end
我想在这里实现的是将cart.id传递到位于transaction.rb中的app_token方法。请注意,这个cart.id并不是要保存到数据库中,我可以通过构建方法通过create方法轻松完成,而是将此cart.id传递给方法以调用其他方法。在app_token方法中,该方法位于transaction.rb模型中。我这样做的原因是因为,我正在与之通信的服务返回一个令牌,我想持有令牌并执行另一个需要cart.id进入的方法。
因此,我只想了解一下,基于上面控制器和模型的给定格式,最推荐的方法是将此cart.id传递到位于transaction.rb模型中的app_token方法中。我想用于方法中的其他功能吗?
谢谢!
答案 0 :(得分:1)
您不需要覆盖 app_token =
# transactions_controller.rb (controller)
@transaction = Transaction.new(app_token: params[:token], item_id: params[:item_id])
@transaction.save
答案 1 :(得分:1)
<强>属性强>
这主要取决于您是否将item_id
设置为虚拟或数据库中的属性。
如果您已经设置了关联foreign_key
,那么您就可以打折我要写的内容,但是如果您还没有,那么您应该考虑以下内容:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
belongs_to :item # -> expects item_id by default
end
如果您没有设置关联(因此没有属性),您将要使用attr_accessor创建虚拟属性:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
attr_accessor :item_id
end
<强> PARAMS 强>
在Rails 4中传递属性实际上是您最不关心的问题 - 您可以根据需要在路径中传递尽可能多的属性。当您尝试将项目与db对象匹配时(因此我的建议)
,会出现问题如果您想传递item_id
属性,则只需确保在视图中设置该属性即可。这可以通过您的routes
完成,也可以在表单中传递:
#config/routes.rb
resources :items
resources :transactions #-> domain.com/items/:item_id/transactions/new
end
这将允许您传递您希望的item_id
(它将作为params[:item_id]
加载到您的控制器中。您还可以使用以下内容:
#app/views/transactions/new.html.erb
<%= form_for @transaction do |f| %>
<%= f.text_field :item_id %>
<%= f.text_field :token %>
<%= f.submit %>
<% end %>
这将使您能够将两个不同的属性发送到您的控制器,然后可以填充如下:
#app/controllers/transactions_controller.rb
class TransactionsController < ApplicationController
def new
@transaction = Transaction.new
end
def create
@transaction = Transaction.new transaction_params
@transaction.save
end
private
def transaction_params
params.require(:transaction).permit(:item_id, :token)
end
end
必须注意,form
方法只有在模型中定义了属性时才可行 - 无论是在数据库中还是虚拟(使用attr_accessor
)
答案 2 :(得分:1)
我有购物车和交易的关联,其中购物车has_many交易和交易belongs_to cart
既然如此,你已经拥有了一个购物车对象,那么在你的控制器中只需从购物车中实例化交易:
transaction = cart.transactions.build app_token: params[:token]
transaction.save
然后 cart_id
将可用于模型中的所有实例方法,因此无需使用与app_token无关的其他逻辑扩展app_token=
。相反,利用ActiveRecord回调。例如,您可以使用before_save
回调来实现您的逻辑:
class Transaction < ActiveRecord::Base
belongs_to :cart
before_save :do_something_with_cart
def do_something_with_cart
# I want to add a few more lines of code here so that I can manipulate cart_id
end
end
如果由于某种原因回调不适合您使用casae,请直接在控制器中调用自定义方法:
transaction = cart.transactions.build app_token: params[:token]
transaction.do_something_with_cart