I would like to pass an additional field, say item_id into these line of codes (both controller and model):
我想传递一个额外的字段,比如说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
That means, I would like my item_id to be passed from the controller to the model so that I can manipulate it do some customization within the model.
这意味着,我希望我的item_id从控制器传递到模型,以便我可以操作它在模型中做一些自定义。
What would be the best way in order to do as such (based on the code above)?
这样做的最佳方法是什么(基于上面的代码)?
===Updated as of 1-Sep-2014 for further details===
===截至2014年9月1日更新了更多详情===
I have an association of cart and transaction in which cart has_many transactions and transaction belongs_to cart; below is the controller;
我有一个购物车和交易协会,其中购物车has_many交易和交易belongs_to cart;以下是控制器;
# transactions_controller.rb (controller)
def new
@transaction = Transaction.new(app_token: params[:token])
end
While the method below is in the model:
虽然以下方法在模型中:
# 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
What I would like to achieve here is to pass in the cart.id into the method of app_token which is located in transaction.rb. Please note that this cart.id is not meant to be saved into the database which I can easily do it via the create method through build, but rather this cart.id is used to be passed into the method to invoke other methods which is located within app_token method which sits in the transaction.rb model. The reason why I am doing this is because, the service which I am communicating with returns a token and I would like to hold the token and perform another method which requires the cart.id to be in.
我想在这里实现的是将cart.id传递给位于transaction.rb中的app_token方法。请注意,这个cart.id并不是要保存到数据库中,我可以通过构建方法通过create方法轻松完成,而是将此cart.id用于传递给方法以调用其他方法。在app_token方法中,它位于transaction.rb模型中。我这样做的原因是因为,我正在与之通信的服务返回一个令牌,我想持有令牌并执行另一个需要cart.id进入的方法。
Thus, I just would like to understand, based on the given format of the controller and model above, what is the most recommended manner to pass in this cart.id into the app_token method which sits in the transaction.rb model which I would want to use for other functions within the method?
因此,我只想了解,基于上面控制器和模型的给定格式,最推荐的方式是将这个cart.id传递到app_token方法,该方法位于transaction.rb模型中,我想要的用于方法中的其他功能?
Thank you!
谢谢!
3 个解决方案
#1
1
I have an association of cart and transaction in which cart has_many transactions and transaction belongs_to cart
我有购物车和交易的关联,其中购物车has_many交易和交易belongs_to购物车
Since that's the case and you already have a cart object, in your controller just instantiate the transaction from the cart:
既然如此,你已经有了一个购物车对象,在你的控制器中只需从购物车中实例化交易:
transaction = cart.transactions.build app_token: params[:token]
transaction.save
cart_id
will then be available to all the instance methods in the model, so there is no need to extend app_token=
with additional logic unrelated to the app_token. Instead, take advantage of ActiveRecord callbacks. For example, you could use a before_save
callback to implement your logic:
然后,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
If for some reason a callback does not fit your use casae, call the custom method directly in the controller:
如果由于某种原因回调不适合您的使用casae,请直接在控制器中调用自定义方法:
transaction = cart.transactions.build app_token: params[:token]
transaction.do_something_with_cart
#2
1
You don't need to override app_token=
您无需覆盖app_token =
# transactions_controller.rb (controller)
@transaction = Transaction.new(app_token: params[:token], item_id: params[:item_id])
@transaction.save
#3
1
Attribute
属性
It will mainly depend on whether you have item_id
set up as an attribute, either virtual or in the database.
它主要取决于您是否将item_id设置为虚拟或数据库中的属性。
If you have an associative foreign_key
set up already, you'll be able to discount what I'm going to write, but in case you haven't, you should consider the following:
如果你已经设置了一个关联的foreign_key,你将可以打折我要写的内容,但是如果你没有,你应该考虑以下内容:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
belongs_to :item # -> expects item_id by default
end
If you don't have an association set up (and hence no attributes), you'll want to use attr_accessor to create a virtual attribute:
如果您没有设置关联(因此没有属性),您将需要使用attr_accessor来创建虚拟属性:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
attr_accessor :item_id
end
Params
PARAMS
Passing attributes in Rails 4 is actually the least of your concerns - you can pass as many attributes through your routes as you wish. The problems occur when you try and match the items with your db objects (hence my recommendation above)
在Rails 4中传递属性实际上是您最不关心的问题 - 您可以根据需要在路径中传递尽可能多的属性。当您尝试将项目与db对象匹配时会出现问题(因此我的建议如上)
If you want to pass the item_id
attribute, you'll just have to ensure it's set in your view. This is either done with your routes
, or by passing it in your form:
如果要传递item_id属性,则只需确保在视图中设置它。这可以通过您的路线完成,也可以在表单中传递:
#config/routes.rb
resources :items
resources :transactions #-> domain.com/items/:item_id/transactions/new
end
This would allow you to pass the item_id
you wish (which will load in your controllers as params[:item_id]
. You can also use the following:
这将允许您传递您希望的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 %>
This will give you the ability to send the two different attributes to your controller, which can then populate as follows:
这将使您能够将两个不同的属性发送到您的控制器,然后可以填充如下:
#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
It must be noted the form
method will only be viable if you have the attribute defined in your model - either in the database, or virtual (with attr_accessor
)
必须注意的是,只有在模型中定义了属性时,表单方法才可行 - 无论是在数据库中还是在虚拟中(使用attr_accessor)
#1
1
I have an association of cart and transaction in which cart has_many transactions and transaction belongs_to cart
我有购物车和交易的关联,其中购物车has_many交易和交易belongs_to购物车
Since that's the case and you already have a cart object, in your controller just instantiate the transaction from the cart:
既然如此,你已经有了一个购物车对象,在你的控制器中只需从购物车中实例化交易:
transaction = cart.transactions.build app_token: params[:token]
transaction.save
cart_id
will then be available to all the instance methods in the model, so there is no need to extend app_token=
with additional logic unrelated to the app_token. Instead, take advantage of ActiveRecord callbacks. For example, you could use a before_save
callback to implement your logic:
然后,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
If for some reason a callback does not fit your use casae, call the custom method directly in the controller:
如果由于某种原因回调不适合您的使用casae,请直接在控制器中调用自定义方法:
transaction = cart.transactions.build app_token: params[:token]
transaction.do_something_with_cart
#2
1
You don't need to override app_token=
您无需覆盖app_token =
# transactions_controller.rb (controller)
@transaction = Transaction.new(app_token: params[:token], item_id: params[:item_id])
@transaction.save
#3
1
Attribute
属性
It will mainly depend on whether you have item_id
set up as an attribute, either virtual or in the database.
它主要取决于您是否将item_id设置为虚拟或数据库中的属性。
If you have an associative foreign_key
set up already, you'll be able to discount what I'm going to write, but in case you haven't, you should consider the following:
如果你已经设置了一个关联的foreign_key,你将可以打折我要写的内容,但是如果你没有,你应该考虑以下内容:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
belongs_to :item # -> expects item_id by default
end
If you don't have an association set up (and hence no attributes), you'll want to use attr_accessor to create a virtual attribute:
如果您没有设置关联(因此没有属性),您将需要使用attr_accessor来创建虚拟属性:
#app/models/transaction.rb
class Transaction < ActiveRecord::Base
attr_accessor :item_id
end
Params
PARAMS
Passing attributes in Rails 4 is actually the least of your concerns - you can pass as many attributes through your routes as you wish. The problems occur when you try and match the items with your db objects (hence my recommendation above)
在Rails 4中传递属性实际上是您最不关心的问题 - 您可以根据需要在路径中传递尽可能多的属性。当您尝试将项目与db对象匹配时会出现问题(因此我的建议如上)
If you want to pass the item_id
attribute, you'll just have to ensure it's set in your view. This is either done with your routes
, or by passing it in your form:
如果要传递item_id属性,则只需确保在视图中设置它。这可以通过您的路线完成,也可以在表单中传递:
#config/routes.rb
resources :items
resources :transactions #-> domain.com/items/:item_id/transactions/new
end
This would allow you to pass the item_id
you wish (which will load in your controllers as params[:item_id]
. You can also use the following:
这将允许您传递您希望的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 %>
This will give you the ability to send the two different attributes to your controller, which can then populate as follows:
这将使您能够将两个不同的属性发送到您的控制器,然后可以填充如下:
#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
It must be noted the form
method will only be viable if you have the attribute defined in your model - either in the database, or virtual (with attr_accessor
)
必须注意的是,只有在模型中定义了属性时,表单方法才可行 - 无论是在数据库中还是在虚拟中(使用attr_accessor)