Ruby on rails 如何在has_many through联接表中保存布尔项

Ruby on rails 如何在has_many through联接表中保存布尔项,ruby-on-rails,has-many-through,Ruby On Rails,Has Many Through,我需要在我的LessonsController中定义一个方法/操作,我可以从lesson show操作调用该方法/操作,该操作将课程标记为当前用户已完成。控制器方法看起来像什么 以下是我的模型概述: User has_many :completions has_many :completed_steps, through: :completions, source: :lesson Lesson has_many :completions has_many :compl

我需要在我的LessonsController中定义一个方法/操作,我可以从lesson show操作调用该方法/操作,该操作将课程标记为当前用户已完成。控制器方法看起来像什么

以下是我的模型概述:

User
   has_many :completions
   has_many :completed_steps, through: :completions, source: :lesson

Lesson
   has_many :completions
   has_many :completed_by, through: :completions, source: :user

Completions
   belongs_to :user
   belongs_to :lesson
我的完成表如下所示:

   t.integer  "user_id"
   t.integer  "lesson_id"
   t.boolean  "completed_step"
   t.string   "completed_by"
resources :lessons do
  get 'complete', on: :member
end
我假设在LessonsController中是这样的

def complete_step
  self.completions.create(completed_step: true, user_id: current_user.id)
end
路线信息:

Rails.application.routes.draw do
  namespace :admin do
  resources :users
  resources :coupons
  resources :lessons
  resources :plans
  resources :roles
  resources :subscriptions
  resources :completions
     root to: "users#index"
  end

devise_for :users, :controllers => { :registrations => "registrations"}

# Added by Koudoku.
 mount Koudoku::Engine, at: 'koudoku'
 scope module: 'koudoku' do
   get 'pricing' => 'subscriptions#index', as: 'pricing'
 end


 resources :lessons do
   member :complete
 end

 # The priority is based upon order of creation: first created -> highest      priority.
 # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
  root 'pages#home'

get '/dashboard' => 'pages#dashboard', :as => 'dashboard'

  mount StripeEvent::Engine, at: '/stripe-events' # prov
end
这是我的按钮链接,可以让它发挥作用

<%= button_to "Mark this Lesson as Complete", complete_lesson_path(@lesson), method: :put, class: "btn btn-warning btn-lg" %>


这能行吗?还是我走远了?谢谢

请在完成控制器中尝试以下代码

def create
  @lession = Lession.find(params[:lession_id]) 
  @completion = current_user.completions.create(completed_step: true, lesson_id: @lesson.id)
  redirected_to @completion
end

保留这是LessonsController,但可以通过以下任一方式进行更改:

def complete_step
  current_user.completions.create(completed_step: true, lesson_id: @lesson.id)
end
# ~~ OR ~~
def complete_step
  @lesson.completions.create(completed_step: true, user_id: current_user.id)
end
这两种方法都假设您已经在控制器中设置了
@lesson
,可能是在\u操作之前的
中:设置\u lesson

编辑:

如果您需要路线建议,那么假设您的路线文件中有
资源:课程
,您可以使用现有路线(可能是
更新
)或添加如下成员路线:

   t.integer  "user_id"
   t.integer  "lesson_id"
   t.boolean  "completed_step"
   t.string   "completed_by"
resources :lessons do
  get 'complete', on: :member
end
如果添加路由,则需要添加如下操作

def complete
  complete_step
  redirect @lesson
end

或者类似,但是您希望处理响应本身。您还需要确保设置了
@lesson
,因此您应该在\u操作:设置\u lesson之前调整
,仅限:[:显示,:更新,]
要包含
:complete
您也可以将
用户:当前用户
传递到
补全。创建
方法,而不是传递
当前用户.id


类似于
@lesson.completions.create(completed\u step:true,user:current\u user)

我尝试这种方法时遇到的错误:找不到'id'=complete\u step的课程这是在CompletionsController中还是在我的LessonsController中,因为我在LessonsController中已经有了create方法@Hardik Upadhyay我的路线是什么样的?参考资料:完成这是一种私人方法吗?关于这条路线有什么建议吗?由你决定,我只是保持了你的问题的相同结构。我假设你是在LessonsController中执行代码的。您的问题是使用
self
而不是
current_user
@lesson
与建立完井控制器相比,这种方法有什么特别的优势吗?这取决于您是否将拥有完整的完井资源。如果是这样,那么有一个完成控制器是有意义的。如果没有,则将其保存在控制器中更干净。如果使用完成控制器,请注意还需要在参数中显式传递课程id,并且需要将其包含在
create
调用中(调整@Hardik的答案,使其看起来像
create(已完成的步骤:true,课程id:completion\u params[:课程id])